Codeforces gym101755H Safe Path(bfs)

题意:

给以一个网格图,有起点终点和一些怪兽,可以上下左右走,不能走到距离怪兽曼哈顿距离为d以内的地方,问到终点最短路径

n*m<=2e5,d<=2e5

思路:

因为n*m的范围,不能直接建2e5*2e5的图,所以要vector.resize()

如果对每个怪兽都预处理的话,复杂度将是O(d2)

所以我们可以让所有怪兽同时走,这样预处理只有O(nm),也可以证明不会漏情况

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional>
     
#define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x))
 
using namespace std;
 
typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL;
 
const db eps = 1e-6;
const int mod = 1e9+7;
const int maxn = 1e6+100;
const int maxm = 1e6+100;
//const int inf = 0x3f3f3f3f;
const int inf = 1e9+7;
const db pi = acos(-1.0);
 

vector<char>a[maxn];
vector<int>v[maxn],vis[maxn],wall[maxn],tp[maxn];
int n,m,d;
int dx[5] = {0,-1,0,1};
int dy[5] = {1,0,-1,0};
bool ck(int x, int y){
    if(x>=1&&x<=n&&y>=1&&y<=m)return true;
    return false;
}
queue<pair<PI, int>>seetq;
void seet(){
    
    while(!seetq.empty()){
        auto top = seetq.front();
        seetq.pop();
        int x = top.fst.fst;
        int y = top.fst.sc;
        int z = top.sc;
        //f(v[x][y])continue;
        //v[x][y]=1;
        if(z==d)continue;
        for(int i = 0; i < 4; i++){
            if(ck(x+dx[i],y+dy[i])&&v[x+dx[i]][y+dy[i]]==0){
                seetq.push({{x+dx[i],y+dy[i]},z+1});
                v[x+dx[i]][y+dy[i]]=1;
            }
        }
    }
    return;
}
PI s,t;
char str[maxn];

int main() {
    scanf("%d %d %d", &n, &m, &d);
    for(int i = 1; i <= n; i++){
        v[i].resize(m+1);
        a[i].resize(m+1);
        vis[i].resize(m+1);
        wall[i].resize(m+1);
        tp[i].resize(m+1);
    }
    
    //getchar();
    for(int i = 1; i <= n; i++){
        scanf("%s",str+1);
        for(int j = 1; j <= m; j++){
            v[i][j]=vis[i][j]=wall[i][j]=0;
            tp[i][j]=inf;
            char c = str[j];
            a[i][j] = c;
            if(c=='S'){
                s = {i,j};
            }
            else if(c=='F'){
                t = {i,j};
            }
            else if(c=='M'){
                wall[i][j]=d+1;
                seetq.push({{i,j},0});
                v[i][j]=1;
            }
        }
    }
    seet();
    queue<pair<PI,int>>q;
    q.push({{s.fst,s.sc},0});
    int ans = -1;
    if(v[s.fst][s.sc]==1)return printf("-1"),0;
    q.push({{s.fst,s.sc},0});
    while(!q.empty()){
        auto top = q.front();
        q.pop();
        int x = top.fst.fst;
        int y = top.fst.sc;
        int z = top.sc;
        if(x==t.fst&&y==t.sc){
            ans=z;
            break;
        }
        if(vis[x][y])continue;
        vis[x][y]=1;
        for(int i = 0; i < 4; i++){
            int nx = x+dx[i];
            int ny = y+dy[i];
            if(ck(nx,ny)&&vis[nx][ny]==0&&v[nx][ny]!=1){
                q.push({{nx,ny},z+1});
            }
        }
    }
    printf("%d",ans);
    return 0;
}
/*
4
2 2 3
2 3 4
1 4
0
 */

 

posted @ 2019-04-23 16:53  wrjlinkkkkkk  阅读(231)  评论(0编辑  收藏  举报