1. 程式人生 > >【並查集 最小生成樹】POJ2421&&HDU1102:Constructing Roads

【並查集 最小生成樹】POJ2421&&HDU1102:Constructing Roads

post ges say his ble for 圖片 i++ clas

Description

There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two village A and B are connected, if and only if there is a road between A and B, or there exists a village C such that there is a road between A and C, and C and B are connected.

We know that there are already some roads between some villages and your job is the build some roads such that all the villages are connect and the length of all the roads built is minimum.

Input

The first line is an integer N (3 <= N <= 100), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 1000]) between village i and village j.

Then there is an integer Q (0 <= Q <= N * (N + 1) / 2). Then come Q lines, each line contains two integers a and b (1 <= a < b <= N), which means the road between village a and village b has been built.

Output

You should output a line contains an integer, which is the length of all the roads to be built such that all the villages are connected, and this value is minimum.

Sample Input

3
0 990 692
990 0 179
692 179 0
1
1 2

Sample Output

179

題目大意:有N個村莊,編號從1到N,你應該建造一些道路,使每兩個村莊可以相互連接。我們說A和B兩個村莊相連,當且僅當A和B之間有一條公路,或者存在一個村莊C,這樣在A和C之間有一條公路,C和B相通。
我們知道在一些村莊之間已經有一些道路,而你的工作就是修建一些道路,這樣所有的村莊都連接起來,所有修建的道路的長度都是最小的。

第一行是一個整數N(3 <= N <= 100),這是村莊的數量。然後是N行,其中第i行包含N個整數,這N個整數的第j個是村i和村j之間的距離(距離應該是[1,1000]內的整數)。
然後存在整數Q(0≤Q≤N*(N + 1)/ 2)。然後進入Q線,每條線包含兩個整數a和b(1 <= a <b <= N),這意味著a村和b村之間的道路已經建成。

你應該輸出一行包含一個整數,這是所有要建造的道路的長度,這樣所有的村莊都連接起來了,這個值是最小的。

代碼如下: 技術分享圖片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn = 5600;
 7 int n,cnt,q;
 8 struct node
 9 {
10     int u,v;
11     int w;
12 };
13 node edge[110];
14 int mapp[maxn][maxn],fa[maxn];
15 bool cmp(node a,node b)
16 {
17     return a.w<b.w;
18 }
19 void init()
20 {
21     for(int i=0;i<n;i++)
22     {
23         fa[i]=i;
24     }
25 }
26 int findd(int x)
27 {
28     if(fa[x]==x)
29         return x;
30     else
31         return fa[x]=findd(fa[x]);
32 }
33 void Union(int x,int y)
34 {
35     int fx=findd(x),fy=findd(y);
36     if(fx!=fy)
37     {
38         fa[fy]=fx;
39     }
40 }
41 
42 int main()
43 {
44     while(~scanf("%d",&n))
45     {
46         for(int i=1;i<=n;i++)
47         {
48             for(int j=1;j<=n;j++)
49             {
50                 scanf("%d",&mapp[i][j]);
51             }
52         }
53         int num=0;
54         for(int i=1;i<n;i++)
55         {
56             for(int j=i+1;j<=n;j++)
57             {
58                 edge[num].u=i;
59                 edge[num].v=j;
60                 edge[num].w=mapp[i][j];
61                 num++;
62             }
63         }
64         scanf("%d",&q);
65         int a,b;
66         cnt=0;
67         init();
68         for(int i=0;i<q;i++)
69         {
70             scanf("%d%d",&a,&b);
71             if(findd(a)!=findd(b))
72             {
73                 Union(a,b);
74                 cnt++;
75             }
76         }
77         sort(edge,edge+num,cmp);
78         int sum=0;
79         int u,v;
80         for(int i=0;i<num;i++)
81         {
82             u=edge[i].u;
83             v=edge[i].v;
84             if(findd(u)!=findd(v))
85             {
86                 sum+=edge[i].w;
87                 cnt++;
88                 Union(u,v);
89             }
90             if(cnt>=n-1)
91                 break;
92         }
93         cout << sum << endl;
94     }
95     return 0;
96 }
View Code

【並查集 最小生成樹】POJ2421&&HDU1102:Constructing Roads