HDU 1232 畅通工程 并查集

来源:互联网 发布:2016年农业保险数据 编辑:程序博客网 时间:2024/05/19 23:29
<pre name="code" class="cpp">#include <iostream>#include <string>#include <map>using namespace std;int ff[1005],ss[1005],qq[1005];int nn;void ii(int n){    for (int i = 01;i <= n;i++)    {ff[i] = i;ss[i] = 1;    }}int dd(int x)  //路径压缩{if(x != ff[x])ff[x] = dd(ff[x]);return ff[x];}void cc(int a ,int b){int ta = dd(a);//得到的是根int tb = dd(b);if(ta != tb){if(ss[ta] >= ss[tb]){if(ss[ta] == ss[tb])ss[ta]++;ff[tb] = ta;}else    ff[ta] = tb;}}int main(){int N , M;int a,b;int t ,i;while (cin>>N,N){cin>>M;ii(1002);memset(qq,0,sizeof(qq));while(M--){cin>>a>>b;cc(a,b);qq[a]=qq[b] =1;}for (i = 1, t =0;i <= N;i++){if(qq[i]==0 || (dd(i) == i))t++;}cout<<t-1<<endl;}return 0;}
代码二  :
</pre>#include<stdio.h> #include<string.h> int nn; //用来判断是否有重复的连通int ff[100005];//ff[x]表示x的父节点 int qq[100005];//标记数组int ss[100005];//ss[x]表示x的秩void ii(int n) //初始化 { for (int i=0;i<n;i++) {ff[i] = i;ss[i] = 1; }} int dd(int x) //带路径压缩的查找 { if (x!=ff[x]) {ff[x] = dd(ff[x]); }return ff[x];} int cc(int a,int b,int t) //按秩合并 { int ta=dd(a);int tb=dd(b);if (ta != tb){if (ss[ta] >= ss[tb]){ff[tb]=ta;if(ss[ta] == ss[tb])ss[ta]++;}elseff[ta] = tb;t++;}return t;} int main() { int i,m,a,b,t,k,j,n; //int t 为需要增加的路 while(~scanf("%d%d",&n,&m)) {if(!n)return 0;ii(100000); memset(qq,0,sizeof(qq));while(m--){t=0; scanf("%d%d",&a,&b);cc(a,b,t);qq[a]=qq[b]=1;}for (i=1,t=0;i<=n;i++){if (qq[i]==0){for (j=1;j<=n;j++){if(qq[j])t=cc(i,j,t);}qq[i]=1;}}printf("%d\n",t); } return 0; }<pre>

首先套用并查集模板。

分析:要使每个城镇都能连通,实际上是要使每个城镇的所指的根都是同一个城镇,那么这样每个城镇都可以互相连通。

判断需要连通几条路主要的代码就在int cc()里面的if判断中,如果指的根不同,那么就需要t++

畅通工程

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 35299    Accepted Submission(s): 18697

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

Input
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M;随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1到N编号。 注意:两个城市之间可以有多条道路相通,也就是说3 31 21 22 1这种输入也是合法的当N为0时,输入结束,该用例不被处理。 
 

Output
对每个测试用例,在1行里输出最少还需要建设的道路数目。 
 

Sample Input
4 21 34 33 31 21 32 35 21 23 5999 00
 

Sample Output
102998
Hint
Hint
Huge input, scanf is recommended.
 

Source
浙大计算机研究生复试上机考试-2005年



2015-10-18 修改



#include <iostream>#include <algorithm>using namespace std;int ff[1005];int ss[1005];int cnt;void ii(int x){  for(int i=1;i<=x;i++)  {  ff[i] = i;      ss[i] = 1;  }}int dd(int x){if(x != ff[x])ff[x] = dd(ff[x]);return ff[x];}void cc(int a,int b){int ta = dd(a);int tb = dd(b);if(ta != tb){      ff[tb] = ta;   cnt++;}}void main(){    int i,j,k;    int m,t;int n,v,w;while(cin>>n,n){ii(n);scanf("%d",&m);        cnt=0;while(m--){scanf("%d%d",&v,&w);cc(v,w);}printf("%d\n",n-1-cnt);}}

N个城镇需要N-1条道路。

1 0
原创粉丝点击