原题链接:点击此处
题意很清楚,我们来分析下例子:第一行告诉你,一共有4个点,2条路。下面两行告诉你,1、3之间有条路,4、3之间有条路。那么整幅图就被分成了1-3-4和2两部分。只要再加一条路,把2和其他任意一个点连起来,畅通工程就实现了,那么这个这组数据的输出结果就是1。
那该怎么办呢?可以运用上周学的并查集啊!给每个父数组一个初值-1,代表尚未与其他路接通,每连通一个路,便将-1置去,因此和普通并查集不同的地方为初始化应为如下:
for(int i=0;i<=n;i++) pre[i]=-1;
此时Find函数应为:
int Find(int x) { if(pre[x]==-1) return x; return pre[x]=Find(pre[x]);
然后即可简单的写出程序,需要注意的是,需要创建的边数永远为城镇数减一(离散老师讲过~至于什么定理我不记得啦),然后永远有一个根节点未置去-1,程序如下,读者可以自己试试:
#include <iostream> #include <stdio.h> using namespace std; int pre[1010]; int Find(int x) { if(pre[x]==-1) return x; return pre[x]=Find(pre[x]); } void Uion(int x,int y) { x = Find(x); y = Find(y); if(x!=y) pre[y] = x; } int main() { int n,m,a,b; while(scanf("%d",&n)&&n) { scanf("%d",&m); for(int i=0;i<=n;i++) pre[i]=-1; while (m--) { scanf("%d %d",&a,&b); Uion(a,b); } int sum=0; for(int i=0;i<=n;i++) if(pre[i]==-1) sum++; printf("%d ",sum-2); } return 0; }