畅通工程 HDU

来源:互联网 发布:神经网络数据融合 编辑:程序博客网 时间:2024/06/02 06:58

题意:

某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?

思路:

相当于给你一个有好几个点的图,让你求算连通分支数,如果连通分支数为1,则说明整个图是一个整体不需要修路,即修(1-1)条;如果连通分支数为2,则需要一条路,把两个分支连起来,试图成为一个完整连通,即修(2-1)条路;如果连通分支数为3,则需要两条路,把两个分支连起来,试图成为一个完整连通,即修(3-1)条路……如果连通分支数为n,则需要n-1条路,把两个分支连起来,试图成为一个完整连通,即修(n-1)条路。所以本题转化为求连通分支数,然后减1即所求。利用并查集只需要求根是自身的点的个数即可。

//也可以初始要修的路数为(n-1),然后有一个在输入的所有连通的点,如果两个点原本不连通,则将其连通,所修路数减1;即在下面加感叹号的地方 加一句(ans++)即如下:

  if(x!=y) {ans++;   pre[x]=y;}
   


AC代码:


#include <iostream>
#include <cstdio>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>


using namespace std;
int pre[10001];
int n,m;
void chushi()
{
    for(int i=0;i<n;i++)
    {
        pre[i]=i;
    }
}
int root(int x)
{
    if(x!=pre[x])
        pre[x]=root(pre[x]);
    return pre[x];
}


int main()
{
   int a,b;int ans=-1;
   while(scanf("%d",&n)&&n)
   {
       memset(pre,0,sizeof(pre));
       ans=-1;
       scanf("%d",&m);
       if(m==0)
       {
           cout<<n-1<<endl;
           continue;
       }
       chushi();
       for(int i=0;i<m;i++)
       {
           scanf("%d %d",&a,&b);
           int x=root(a);
           int y=root(b);
           if(x!=y)   !!!
            pre[x]=y;


       }
       for(int i=0;i<n;i++)
       {
           if(pre[i]==i)//计算一共几条独立的城市
            ans++;
       }
       cout<<ans<<endl;
   }
}

原创粉丝点击