UVA572 (并查集解法)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA572 (并查集解法)相关的知识,希望对你有一定的参考价值。

紫书第六章的题,用并查集重写一遍,果然还是书上给的dfs方法更简单......

一开始用fa[i*m+j] != i*m+j 来判断是否访问过,虽然没想出来为什么WA,但是确实不如用vis稳

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int fa[10500],m,n,cnt,vis[105][105];
char mp[105][105];
int find(int x){return fa[x] == x?x:fa[x] = find(fa[x]);}
void merge(int x,int y){
    int fx = find(x);
    int fy = find(y);
    if(fx == fy) return ;
    fa[fx] = fy;
}
void dfs(int x,int y,int fx,int fy){
    if(x<0 || x>=m || y<0 || y>=n) return;
    if(vis[x][y] || mp[x][y] == *) return;
    vis[x][y] = 1;
    //cout<<"x || y || fx || fy : "<<x<<" || "<<y<<" || "<<fx<<" || "<<fy<<endl;
    if(fx != -1) merge(x*m+y,fx*m+fy);
    for(int i = -1;i<2;i++){
        for(int j = -1;j<2;j++){
            if(!i && !j) continue;
            dfs(x+i,y+j,x,y);
        }
    }
}
int main(){
    while(scanf("%d%d",&m,&n) == 2 && m && n){
        cnt = 0;
        memset(vis,0,sizeof(vis));
        for(int i = 0;i<m;i++) scanf("%s",mp[i]);
        for(int i = 0;i<10500;i++) fa[i] = i;
        for(int i = 0;i<m;i++)
            for(int j = 0;j<n;j++)
                if(!vis[i][j] && mp[i][j] == @) dfs(i,j,-1,-1),cnt++;
        printf("%d\n",cnt);
    }
    return 0;
}

 

以上是关于UVA572 (并查集解法)的主要内容,如果未能解决你的问题,请参考以下文章

LC 200, 721,684 并查集解法

1013 Battle Over Cities(并查集解法)

UVa 572 Oil Deposits(简单DFS)

UVA 572 -- Oil Deposits(DFS求连通块+种子填充算法)

UVA 572 Oil Deposits(DFS求连通块)

紫书Oil Deposits UVA - 572 dfs求联通块