Constructing Roads POJ - 2421 (最小生成树)

思路:首先使用二维数组dis[][]处理输入, 对于已经修好的路,将其对应的dis[i][j]置为零即可。最后再将

      所有的dis[][]保存到边结构体中,使用Kruskal算法求得最小生成树。

 1 #include<iostream>
 2 #include<vector>
 3 #include<string>
 4 #include<cmath>
 5 #include<set>
 6 #include<algorithm>
 7 #include<cstdio>
 8 #include<map>
 9 #include<cstring>
10 
11 using namespace std;
12 
13 int dis[110][110];
14 struct Edge
15 {
16     int a, b;
17     int cost;
18 }edge[1000010];
19 
20 int Tree[110];
21 
22 int findRoot(int x)
23 {
24     if(Tree[x] == -1)
25         return x;
26     int tmp = findRoot(Tree[x]);
27     Tree[x] = tmp;
28     return tmp;
29 }
30 
31 bool cmp(Edge e1, Edge e2)
32 {
33     return e1.cost < e2.cost;
34 }
35 
36 int main()
37 {
38     int n;
39     scanf("%d", &n);
40     for(int i = 1; i <= n; ++i)
41         Tree[i] = -1;
42         
43     for(int i = 1; i <= n; ++i)
44         for(int j = 1; j <= n; ++j)
45             scanf("%d", &dis[i][j]);
46     
47     int q;
48     scanf("%d", &q);
49     for(int i = 1; i <= q; ++i)
50     {
51         int a, b;
52         scanf("%d %d", &a, &b);
53         dis[a][b] = 0;
54     }
55     
56     int k = 1;
57     for(int i = 1; i <= n; ++i)
58         for(int j = 1; j <= n; ++j)
59         {
60             if(i != j && i < j)    // 注意同一条边不要重复保存! 
61             {
62                 edge[k].a = i;
63                 edge[k].b = j;
64                 edge[k].cost = dis[i][j];
65                 ++k;
66             }
67         }
68     sort(edge+1, edge+k, cmp);
69     int ans = 0;
70     for(int i = 1; i < k; ++i)
71     {
72         int ra = findRoot(edge[i].a);
73         int rb = findRoot(edge[i].b);
74         if(ra != rb)
75         {
76             Tree[ra] = rb;
77             ans += edge[i].cost;
78         }    
79     }
80     
81     printf("%d\n", ans);
82     
83     return 0;
84 }

猜你喜欢

转载自www.cnblogs.com/FengZeng666/p/11404856.html