洛谷 - P1141 - 01迷宫 - dfs

https://www.luogu.org/problemnew/show/P1141

能互相到达的格子的答案自然是一样的,第一次dfs标记联通块,第二次dfs把cnt传递到整个联通卡并顺手消除vis标记(其实把vis标记改成另一个也可以的)。

#include<bits/stdc++.h>
using namespace std;
#define ll long long

int n,m;
int g[1005][1005];
int ans[1005][1005];

int cnt=0;
int vis[1005][1005];

void dfs(int r,int c){
    //printf("%d %d\n",r,c);
    vis[r][c]=1;
    cnt++;
    if(r-1>=1&&vis[r-1][c]==0&&g[r][c]!=g[r-1][c])
        dfs(r-1,c);
    if(r+1<=n&&vis[r+1][c]==0&&g[r][c]!=g[r+1][c])
        dfs(r+1,c);
    if(c-1>=1&&vis[r][c-1]==0&&g[r][c]!=g[r][c-1])
        dfs(r,c-1);
    if(c+1<=n&&vis[r][c+1]==0&&g[r][c]!=g[r][c+1])
        dfs(r,c+1);
}

void dfs2(int r,int c){
    vis[r][c]=0;
    ans[r][c]=cnt;
    if(r-1>=1&&vis[r-1][c])
        dfs2(r-1,c);
    if(r+1<=n&&vis[r+1][c])
        dfs2(r+1,c);
    if(c-1>=1&&vis[r][c-1])
        dfs2(r,c-1);
    if(c+1<=n&&vis[r][c+1])
        dfs2(r,c+1);
}


int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            scanf("%1d",&g[i][j]);
            //printf("%d!\n",g[i][j]);
        }
    }

    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(ans[i][j]==0){
                cnt=0;
                //memset(vis,0,sizeof(vis));
                dfs(i,j);
                dfs2(i,j);
            }
        }
    }

    for(int i=1;i<=m;i++){
        int r,c;
        scanf("%d%d",&r,&c);
        printf("%d\n",ans[r][c]);
    }
}

 

posted @ 2019-04-05 14:17  韵意  阅读(151)  评论(0编辑  收藏  举报