题目
http://acm.hdu.edu.cn/showproblem.php?pid=1232
问题分析
本题求还需要建设多少条道路使全省畅通,并且给出了已有道路,把村庄作为顶点,已有道路作为边,求出连通分支的个数再-1即可。
算法
算法核心
根据已有道路构建并查集,最后计算出连通分支数-1即可。
算法流程
首先将所有结点的根结点初始化为本身,然后每输入一条边,就看两个顶点是否在同一个连通分支中,即用find_()函数看两个顶点的根结点是否相同,如果相同就继续输入,如果不同,就将两顶点所在的连通分支合并,注意这里是将连通分支合并,。所有边遍历完之后,再遍历顶点,如果一个顶点的根结点是它本身,则连通分支数增加,最后连通分支数-1即为所求。
数据结构
并查集,如感兴趣可移步畅通工程系列1
代码实现
记得要注意看清城镇数和道路数的变量哦,跟畅通工程系列1的HDU1863正好相反。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1005;
int root[maxn];
int n,m;//城镇数,道路数
int cnt;//连通分支个数
void init()
{
for(int i=0; i<maxn; ++i)
root[i]=i;
cnt=0;
}
int find_(int x)
{
if(x==root[x])
return x;
else
{
root[x]=find_(root[x]);
return root[x];
}
}
void cal()//计算连通分支数目
{
for(int i=1; i<=n; ++i)
if(i==root[i])
cnt++;
}
int main()
{
while(scanf("%d%d",&n,&m)==2&&n)
{
int i;
int a,b,fa,fb;
init();
for(i=1; i<=m; ++i)
{
scanf("%d%d",&a,&b);
fa=find_(a);
fb=find_(b);
if(fa!=fb)
{
if(fa<fb)
root[fb]=fa;//注意不是把b往上连,而是把b所在的连通分支往上连
else
root[fa]=fb;
}
}
cal();
printf("%d\n",cnt-1);
}
return 0;
}