HDU 1102 Constructing Roads

http://acm.hdu.edu.cn/showproblem.php?pid=1102

题意:

有N个村庄,编号从1到N,你应该建立一些道路,使每两个村庄可以连接到彼此。我们说两个村庄A和B连接,当且仅当在A和B之间有道路,或者存在一个村庄C,使得在A和C之间有道路,并且C和B连接。
我们知道,一些村庄之间已经有一些道路,你的工作是建造一些道路,使所有的村庄都连接,所有建设的道路的长度是最小的。
 
思路:
普里姆算法或克鲁斯卡尔算法。
 1 #include<iostream> 
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 const int maxn = 100 + 5;
 7 
 8 int n, cnt, ans;
 9 
10 //
11 struct node
12 {
13     int u;    //边的起点
14     int v;    //边的终点
15     int w;    //边的权重
16 }edge[maxn*maxn];
17 
18 int p[maxn];
19 
20 int find(int x)
21 {
22     return p[x] == x ? x : find(p[x]);
23 }
24 
25 bool cmp(node a, node b)
26 {
27     return a.w < b.w;
28 }
29 
30 void Kruskal()
31 {
32     //首先按权重从小到大排序
33     sort(edge, edge + cnt, cmp); 
34     //依次选择权重小的
35     for (int i = 0; i < cnt; i++)
36     {
37         int x = find(edge[i].u);
38         int y = find(edge[i].v);
39         //如果没有添加,就添加上去
40         if (x == y)  continue;
41         ans += edge[i].w;
42         p[x] = y;
43     }
44 }
45 
46 int main()
47 {
48     //freopen("D:\\txt.txt", "r", stdin);
49     while (cin >> n)
50     {
51         for (int i = 1; i <= n; i++)
52             p[i] = i;
53         cnt = 0;
54         for (int i = 1; i <= n;i++)
55         for (int j = 1; j <= n; j++)
56         {
57             edge[cnt].u = i;
58             edge[cnt].v = j;
59             cin >> edge[cnt].w;
60             cnt++;
61         }
62         int m;
63         int a, b;
64         cin >> m;
65         while (m--)
66         {
67             cin >> a >> b;
68             int x = find(a);
69             int y = find(b);
70             p[x] = y;
71         }
72         ans = 0;
73         Kruskal();
74         cout << ans << endl;
75     }
76     return 0;
77 }

 

posted @ 2017-02-10 16:56  Kayden_Cheung  阅读(433)  评论(0编辑  收藏  举报
//目录