hdoj1879 继续畅通工程(Prime || Kruskal)
Posted ColdCode
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdoj1879 继续畅通工程(Prime || Kruskal)相关的知识,希望对你有一定的参考价值。
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1879
思路
这题和hdoj1102很像,图中的有一些路已经修好了,对于这些已经修好的路,我们令还需要修的长度为0即可,然后进行Prime算法或者Kruskal算法。
代码
Prime算法:
1 #include <algorithm> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int INF = 0x7fffffff; 7 const int N = 100 + 10; 8 int map[N][N]; 9 int dist[N]; 10 int n; 11 12 void prime() 13 { 14 int min_edge, min_node; 15 for (int i = 1; i <= n; i++) 16 dist[i] = INF; 17 int ans = 0; 18 int now = 1; 19 for (int i = 1; i < n; i++) 20 { 21 dist[now] = -1; 22 min_edge = INF; 23 for (int j = 1; j <= n; j++) 24 { 25 if (j != now&& dist[j] >= 0) 26 { 27 if (map[now][j] >= 0) //注意是map[now][j]>=0,因为有些路已经修好了,初始化时令其长度为0 28 dist[j] = min(dist[j], map[now][j]); 29 if (dist[j] < min_edge) 30 { 31 min_edge = dist[j]; // //min_edge存储与当前结点相连的最短的边 32 min_node = j; 33 } 34 } 35 } 36 ans += min_edge; // //ans存储最小生成树的长度 37 now = min_node; 38 } 39 printf("%d\n", ans); 40 } 41 42 int main() 43 { 44 //freopen("hdoj1879.txt", "r", stdin); 45 while (scanf("%d", &n) == 1 && n) 46 { 47 memset(map, 0, sizeof(map)); 48 int a, b, d, s; 49 for (int i = 0; i < n*(n - 1) / 2; i++) 50 { 51 scanf("%d%d%d%d", &a, &b, &d, &s); 52 if (s == 0) 53 map[a][b] = map[b][a] = d; 54 else if (s == 1) map[a][b] = map[b][a] = 0; 55 } 56 prime(); 57 } 58 return 0; 59 }
Kruskal算法:
1 #include <algorithm> 2 #include <cstring> 3 #include <cstdio> 4 #include <vector> 5 using namespace std; 6 7 struct Edge 8 { 9 int a, b, dist; 10 11 Edge() {} 12 Edge(int a, int b, int d) :a(a), b(b), dist(d) {} 13 bool operator < (Edge edge) 14 { 15 return dist < edge.dist; 16 } 17 }; 18 19 const int N = 100 + 10; 20 vector<Edge> v; 21 int p[N]; 22 int n; 23 24 int find_root(int x) 25 { 26 if (p[x] == -1) 27 return x; 28 else return find_root(p[x]); 29 } 30 31 void kruskal() 32 { 33 memset(p, -1, sizeof(p)); 34 sort(v.begin(), v.end()); //将边按边长从短到长排序 35 int ans = 0; 36 for (int i = 0; i < v.size(); i++) 37 { 38 int ra = find_root(v[i].a); 39 int rb = find_root(v[i].b); 40 if (ra != rb) 41 { 42 ans += v[i].dist; 43 p[ra] = rb; 44 } 45 } 46 printf("%d\n", ans); 47 } 48 49 int main() 50 { 51 //freopen("hdoj1879.txt", "r", stdin); 52 while (scanf("%d", &n) == 1 && n) 53 { 54 v.clear(); 55 int m = n*(n - 1) / 2; 56 int a, b, d, s; 57 for (int i = 0; i < m; i++) 58 { 59 scanf("%d%d%d%d", &a, &b, &d, &s); 60 if (s == 0) 61 v.push_back(Edge(a, b, d)); 62 else if (s == 1) v.push_back(Edge(a, b, 0)); 63 } 64 kruskal(); 65 } 66 return 0; 67 }
以上是关于hdoj1879 继续畅通工程(Prime || Kruskal)的主要内容,如果未能解决你的问题,请参考以下文章