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)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1879 继续畅通工程

HDU 1879 - 继续畅通工程

HDU 1879 继续畅通工程

HDU 1879 继续畅通工程 (并查集)

HDU1879--继续畅通工程(最小生成树)

杭电1879继续畅通project