SDAU练习四 1003

来源:互联网 发布:数据库类型有哪些 编辑:程序博客网 时间:2024/05/17 08:57

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

解题思路:题目大意就是求可以最少多少条线把子连通图连起来使其成为一个大的连通图。这道题用并查集的方法将每个子连通图表示成每个独立的集合,然后求有多少个集合即可。难点就在于如何表示成集合。首先创建数组,初始化时候看城镇的个数,数组的标号等于数组的值,表示每个城镇对应的是不同的集合,也就是一开始每个城镇都是独立的个体,然后开始添加道路。输入2个城镇,首先找到每个城镇的集合号,如果这两个城镇的集合号相同,那么表示着2个城镇是互通的,不需要再动了;如果不相同,表示他们有着共同的双亲,将一个城镇的集合号数作为城镇赋值给另个城镇的集合号数的集合号,简而言之就是并入同一个集合,他们是祖先也就成为了集合号数,也就是树的根节点。对于输出,判断有都是个独立的集合即可。

做题感想:感觉是一个新的东西,一开始有点难接受,不是特别明白,而且只讲了一个例题,觉得有点疑惑,这个方法是不是只是针对一特定的题目,适用性好像不是很强,最后代码有借鉴成分。

AC代码:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include<iostream>  
  2. using namespace std;  
  3. int arr[1000];  
  4. int find(int x)  
  5. {  
  6.     int r=x;  
  7.     while(arr[r]!=r)  
  8.        r=arr[r];  
  9.     return r;  
  10. }  
  11. void merge(int x,int y)  
  12. {  
  13.     int a,b;  
  14.       a=find(x);  
  15.       b=find(y);  
  16.     if(a!=b)  
  17.       arr[a]=b;  
  18. }  
  19. int main()  
  20. {  
  21.   
  22.     int i,a,b;  
  23.     int x,y;  
  24.     int count;  
  25.     while(cin>>a)  
  26.     {  
  27.         if(a)  
  28.         {  
  29.             cin>>b;  
  30.             count=0;  
  31.             for(i=1;i<=a;i++)  
  32.              arr[i]=i;  
  33.             for(i=1;i<=b;i++)  
  34.             {  
  35.                 cin>>x>>y;  
  36.                merge(x,y);  
  37.             }  
  38.            for(count=-1,i=1;i<=a;i++)  
  39.              if(arr[i]==i)  
  40.                count++;  
  41.         cout<<count<<endl;  
  42.         }  
  43.     }  
  44.     return 0;  
  45. }  
0 0
原创粉丝点击