HDU-1102-Constructing Roads
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1102
题意:
有N多个小镇,现在需要建路使所有小镇相通,间接跟直接,给你这些小镇直接的距离,但是有些小镇是已经有路相连的了,所以这两个小镇之间就不用再建路。
方法:
用了prim跟kruskal都可以做出来,其实就是求最小生成树。只要把已经有路相通的两个小镇的距离改为0即可,不过在开数组时应该是开n*n*2,其他的就一如既往了。
没什么特别要注意的!都是练习Kruskal跟prim算法的习题。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<algorithm> 3 #include<string> 4 using namespace std; 5 6 const int maxn = 100+10; 7 int far[maxn]; 8 int n, m; 9 int k; 10 11 struct Edge 12 { 13 bool operator<(const Edge &n)const 14 { 15 return value<n.value; 16 } 17 int strat; 18 int end; 19 int value; 20 }edge[maxn*maxn*2]; 21 22 bool cmp(Edge &a, Edge &b) 23 { 24 return a.value < b.value; 25 } 26 27 void init() 28 { 29 for(int i=0; i<=n; i++) 30 far[i] = i; 31 } 32 33 int find(int x) 34 { 35 if(far[x] != x) 36 return far[x] = find(far[x]); 37 return far[x]; 38 } 39 40 void uni(int a, int b) 41 { 42 a = find(a); 43 b = find(b); 44 if(a != b) 45 far[b] = a; 46 } 47 48 49 int kruskal() 50 { 51 init(); 52 sort(edge, edge+k, cmp); 53 int sum = 0; 54 int time=1; 55 for(int i=1; i< k && time<n; i++) 56 { 57 int a = edge[i].strat; 58 int b = edge[i].end; 59 if(find(a) != find(b)) 60 { 61 uni(a, b); 62 time++; 63 sum += edge[i].value; 64 } 65 } 66 return sum; 67 } 68 int main() 69 { 70 71 int i, j; 72 int a, b, c; 73 while(cin>>n) 74 { 75 k=1; 76 for(i=1; i<=n; i++) 77 { 78 for(j=1; j<=n; j++) 79 { 80 scanf("%d", &c); 81 edge[k].strat = i; 82 edge[k].end = j; 83 edge[k++].value = c; 84 } 85 } 86 cin>>m; 87 for(i=0; i<m; i++) 88 { 89 scanf("%d%d", &a, &b); 90 edge[k].strat = a; 91 edge[k].end = b; 92 edge[k++].value = 0; 93 edge[k].strat = b; 94 edge[k].end = a; 95 edge[k++].value = 0; 96 } 97 printf("%d\n", kruskal()); 98 } 99 return 0; 100 } 101 102 103 104 105 106 107 /*#include<iostream> 108 #include<string> 109 using namespace std; 110 111 const int INF = 0x4fffffff; 112 const int maxn = 100+10; 113 int map[maxn][maxn]; 114 int dis[maxn]; 115 bool used[maxn]; 116 int n, m; 117 118 void init() 119 { 120 int i, j; 121 for(i=0; i<=n; i++) 122 { 123 for(j=0; j<=n; j++) 124 { 125 map[i][j] = i==j?0:INF; 126 } 127 dis[i] = INF; 128 } 129 memset(used, false, sizeof(used)); 130 } 131 132 int prim() 133 { 134 dis[1]=0; 135 used[1] = true; 136 int minNode; 137 int min; 138 int sum = 0; 139 for(int i=1; i<=n; i++) 140 { 141 min = INF; 142 minNode = 1; 143 for(int j=1; j<=n; j++) 144 { 145 if(dis[j]<min && !used[j]) 146 { 147 min = dis[j]; 148 minNode = j; 149 } 150 } 151 sum += dis[minNode]; 152 used[minNode] = true; 153 for(int k=1; k<=n; k++) 154 { 155 if(dis[k]>map[minNode][k] && !used[k]) 156 { 157 dis[k] = map[minNode][k]; 158 } 159 } 160 } 161 return sum; 162 } 163 164 165 int main() 166 { 167 int i, j; 168 int a, b; 169 while(cin>>n) 170 { 171 init(); 172 for(i=1; i<=n; i++) 173 for(j=1; j<=n; j++) 174 { 175 scanf("%d", &map[i][j]); 176 } 177 scanf("%d", &m); 178 for(i=1; i<=m; i++) 179 { 180 scanf("%d%d", &a, &b); 181 map[a][b] = map[b][a] = 0; 182 } 183 printf("%d\n", prim()); 184 } 185 return 0; 186 }*/