畅通工程 HDU

来源:互联网 发布:域名注册购买 编辑:程序博客网 时间:2024/05/30 23:25

题意是给第一行两个数,n是城市数,m是给出的已经形成通路的道路数,求还需要多少个通道才能使每两个城市之间都形成通路。

上篇博客文章讲了并查集,知道了并查集就很容易做出来,可以这样想,由给出的数据先算出目前已经有了多少个互相形成同路的集合
拿题目中给出的数据举个例子
4 2
1 3
4 3
其中 1 3 4 已经形成通路,2单独形成一个通路,因此如果想要城市之间两两形成同路,则只需要再构成一个2和1,3,4任意一个城市的通路即可。故存在两个集合则
需要再修answer=1条路。依次类推,每次根据数据先算出共有几个集合,answer就是集合数目-1。
代码如下

#include<cstdio>#include<iostream>using namespace std;int pre[2000];int Find(int x){    int r=x;    while(r!=pre[r])//若r的前导点不是它本身    {        r=pre[r];//查找    }    //路径压缩    int i=x,j;    while(pre[i]!=r)    {        j=pre[i];        pre[i]=r;        i=j;    }    return r;//返回查找到的根节点}//合并void join(int x,int y){    int rx=Find(x),ry=Find(y);    //cout<<"rx="<<rx<<" ry="<<ry<<endl;    if(rx!=ry)    {        pre[rx]=ry;    }}int main(){    int n,m;    while(cin>>n>>m&&n)    {        int answer;        if(!n)            break;        for(int i=1; i<=n; ++i)            pre[i]=i;//初始化        int a,b;        for(int i=1; i<=m; ++i)        {            cin>>a>>b;            join(a,b);        }        int i;        for(answer=0,i=1; i<=n; ++i)        {            if(i==pre[i])                ++answer;            //cout<<pre[i]<<" ";        }        cout<<answer-1<<endl;    }}
原创粉丝点击