HDU1232 畅通工程 (并查集)

时间:2021-03-12 09:53:52

题目:中文的就不说了~~~~

思路:属于并查集的基础题,比较典型,可以把连通在一起的看成是一个点,假设一共有N个独立的点,那么就需要 N - 1 条边把他们连通起来,所以利用并查集算法,最后统计有多少个独立的集合,然后把这个数减去一便是我们所要的答案了~~~~

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <algorithm>
using namespace std;
const int MAXN = 1e3 + 3;
int pre[MAXN]; //保存的是父节点的值
bool root[MAXN]; //是否为根节点

int Find(int x)
{
int r = x;
while(pre[r] != r)
{
r = pre[r];
}
int i = x,j;
while(pre[i] != r)
{
j = i;
i = pre[i];
pre[j] = r;
}
return r;
}

void mix(int a,int b)
{
int x = Find(a);
int y = Find(b);
if(x > y)
{
pre[x] = y;
}
if(x < y)
{
pre[y] = x;
}
}

int main()
{
int M,N;
while(~scanf("%d",&M)&&M)
{
scanf("%d",&N);
for(int i = 1; i <= M; i++)
{
pre[i] = i;
root[i] = false;
}
while(N--)
{
int a,b;
scanf("%d%d",&a,&b);
mix(a,b);
}
for(int i = 1; i <= M; i++)
{
if(pre[i] == i)
root[i] = true;
}
int ans = 0;
for(int i = 1; i <= M; i++)
{
if(root[i]) ans ++;
}
printf("%d\n",ans-1);
}
return 0;
}