题目 http://acm.hdu.edu.cn/status.phpuser=talent_jian&pid=1232&status=5
这是一道 并查集的模板题
先让我回顾下什么事 并查集
一般会 我们会 合并集合,而合并集合的话 又需要知道 集合的爸爸 ,所以这时候就出现了 2个常见的函数;
1.找爸爸
int findfather(int dest)
{
if (father[dest] == dest) //如果当前的是爸爸,就返回。
return dest;
else return findfather(father[dest]); //如果 不是爸爸,就继续找爸爸~
}
循环写法的找爸爸
while (father[dest] != dest)
{
dest = findfather(father[dest]);
}
return dest;
2.
合并 集
int combine(int a,int b)
{
int x, y;
x = findfather(a);
y = findfather(b);
if (x != y)
{
father[x] = y;
return 1;
}
else return 0;
}
接下来 的是AC的代码
#include<iostream>
#include<cstring>
using namespace std;
int father[1005];
void init()
{
for (int i = 0; i <= 1005; i++)
{
father[i] = i;
}
}
int findfather(int dest)
{
if (father[dest] == dest)
return dest;
else return findfather(father[dest]);
}
int combine(int a,int b)
{
int x, y;
x = findfather(a);
y = findfather(b);
if (x != y)
{
father[x] = y;
return 1;
}
else return 0;
}
int main()
{
int n, m,x,y,ans;
while (cin >> n >> m,n)
{
init(); ans = 0;
for (int i = 0; i < m; i++)
{
cin >> x >> y;
combine(x, y);
}
for (int i = 1; i <= n; i++)
{
if (father[i] == i)
ans++;
}
cout << ans-1 << endl; // -1 是因为要减去真正的爸爸
}
}