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; }