#include<cstdio> #include<cstring> using namespace std; const int MAX_N =1011; int par[MAX_N]; int rank1[MAX_N]; void init(int n) { for(int i=1; i<=n; i++) { par[i]=i; rank1[i]=0; } } int find1(int x) { if(par[x]==x) return x; else return par[x]=find1(par[x]); } void unite(int x,int y) { x=find1(x); y=find1(y); if(x==y) return; if(rank1[x]<rank1[y]) par[x]=y; else { par[y]=x; if(rank1[x]==rank1[y]) rank1[x]++; } } bool same(int x,int y) { return find1(x)==find1(y); } int main() { int kase; scanf("%d",&kase); while(kase--) { memset(par,0,sizeof(par)); memset(rank1,0,sizeof(rank1)); int n,s,x,y,ans=0; scanf("%d%d",&n,&s); init(n); for(int i=0; i<s; i++) { scanf("%d%d",&x,&y); unite(x,y); } for(int i=1;i<=n;i++) if(par[i]==i) ans++; printf("%d\n",ans); } }
并查集的简单应用,注意边界,注意清空。
套了模板,没有注意边界,错了多次。
我看到的优秀代码http://www.cnblogs.com/liaoguifa/archive/2012/12/17/2821690.html
<pre name="code" class="cpp">#include<stdio.h> #include<string.h> int father[1002]; int find(int n) { if(father[n] == n) return n; else return father[n] = find(father[n]); } int main() { int n, m, T, x, y, cnt, i, j; scanf("%d", &T); while(T--) { cnt = 0; scanf("%d%d", &n, &m); for(i=0; i<n; ++i) father[i] = i; for(i=0; i<m; ++i) { scanf("%d%d", &x, &y); x = find(x-1), y = find(y-1); if(x != y) father[x] = y; } for(i=0; i<n; ++i) if(father[i] == i) cnt++; printf("%d\n", cnt); } return 0; }