AC了,但有疑问
查看原帖
AC了,但有疑问
1504052
plmoknijbuhv楼主2025/2/6 13:45

思路:如果一个点上存在领主,那么从这个点开始广搜,搜到最近的感染源,将该点上所有领主的感染时间进行更新。许多点都是七八百毫秒过去的,看了题解我的思路似乎是错的,但为什么能通过?

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;

int n,m,a,b;//四个数字
int xx[] = {1,0,-1,0};
int yy[] = {0,1,0,-1};
vector<int> id[505][505];//存储某个点上的领主
bool map[505][505];//存储感染源
int tim[100005];//感染时间

void bfs(int bx,int by){
    if(map[bx][by]) return;//感染源与领主重叠
    bool seen[505][505];//标记访问过的节点
    int dist[505][505];//存储时间
    queue<pair<int,int>> q;
    memset(seen,false,sizeof(seen));
    q.push({bx,by});
    seen[bx][by] = true;
    dist[bx][by] = 0;

    while(!q.empty()){
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        
        for(int i = 0;i < 4;i++){
            int nx = x + xx[i];
            int ny = y + yy[i];
            if(nx < 1 || nx > n || ny < 1 || ny > m || seen[nx][ny]) continue;
            seen[nx][ny] = true;
            dist[nx][ny] = dist[x][y] + 1;
            if(map[nx][ny]){//找到感染源,更新
                for(int j = 0;j < id[bx][by].size();j++)
                    tim[id[bx][by][j]] = dist[nx][ny];
                return;
            }
            q.push({nx,ny});
        }
    }
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);

    cin >> n >> m >> a >> b;
    for(int i = 1;i <= a;i++){
        int x,y;
        cin >> x >> y;
        map[x][y] = true;//输入感染源
    }
    for(int i = 1;i <= b;i++){
        int x,y;
        cin >> x >> y;
        id[x][y].push_back(i);//输入领主
    }
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= m;j++){
            if(id[i][j].size() != 0)//size不为0代表有领主
                bfs(i,j);
        }
    }
    for(int i = 1;i <= b;i++){
        cout << tim[i] << endl;//输出
    }
}
2025/2/6 13:45
加载中...