思路:首先使用二维数组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 }