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