1. 程式人生 > >2612 bfs加打表

2612 bfs加打表

打表預處理會降低複雜度,如果每次找一個'@'都跑一次bfs的話會超時;

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const double epos=1e-8;
const int maxn=209;
int n,m;

int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};

char a[maxn][maxn];//圖;
int flag[maxn][maxn];

struct Node{
    int x,y;
}s1,s2,dnode;//s1表示Y位置,s2表示M位置,dnode表示移動後的位置;

int check(int i,int j){
    if(i>=0&&i<n&&j>=0&&j<m&&flag[i][j]==0&&(a[i][j]=='.'||a[i][j]=='@'))
        return 1;
    return 0;
}

int step[maxn][maxn][2];//預處理打表記錄Y,M到每個點的距離;

queue<Node>q;
void bfs(Node st,int fff){
    memset(flag,0,sizeof(flag));
    while(!q.empty())
        q.pop();
    flag[st.x][st.y]=1;
    q.push(st);
    while(!q.empty()){
        Node tan1=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            dnode.x=tan1.x+dx[i];
            dnode.y=tan1.y+dy[i];
            if(check(dnode.x,dnode.y)){
                flag[dnode.x][dnode.y]=1;
                step[dnode.x][dnode.y][fff]=step[tan1.x][tan1.y][fff]+1;
                q.push(dnode);

            }

        }
    }
}

int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        memset(step,0,sizeof(step));
        for(int i=0;i<n;i++)
            scanf("%s",a[i]);
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++){
                if(a[i][j]=='Y'){
                    s1.x=i,s1.y=j;
                    bfs(s1,0);
                }
                if(a[i][j]=='M'){
                    s2.x=i,s2.y=j;
                    bfs(s2,1);
                }
            }
        //若兩點之間沒有路,不可達,一開始初始化是0,
        //由於需要求最小的值,所以需要將沒有路的改為無窮大
        for(int h=0;h<2;h++)
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                    if(step[i][j][h]==0)
                        step[i][j][h]=inf;

        int minn=inf;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(a[i][j]=='@')
                    minn=min(minn,step[i][j][0]+step[i][j][1]);
        printf("%d\n",minn*11);
    }

    return 0;
}