题目传送门:畅通工程
//简单入门的并查集
#include <iostream>
using namespace std;
int pre[1010];
int find(int x)
{
int r = x;
while (pre[r] != r)
r = pre[r];
int i = x, j;
while (i != r)
{
j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
int main()
{
int n, m, p1, p2, i, total, f1, f2;
while (cin >> n && n)
{
total = n-1;
for (int i = 1; i<=n; i++) //从1编号到n,每个点的上级都是自己
pre[i] = i;
cin >> m;
while (m --) //共m条路,下面的代码就是join函数
{
cin >> p1>> p2; //每次读入一条路,看他的端点p1,p2是否已经在一个连通分支里了
f1 = find(p1);
f2 = find(p2); //如果不连通,那么把这两个分支连接起来
if (f1!= f2)
{
pre[f2] = f1;
total--;
}
}
cout << total<< endl;
}
return 0;
}