hdoj1233 还是畅通工程(Prime || Kruskal)

Posted ColdCode

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdoj1233 还是畅通工程(Prime || Kruskal)相关的知识,希望对你有一定的参考价值。

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=1233

思路

最小生成树问题,使用Prime算法或者Kruskal算法解决。

代码

Prime算法:

 1 #include <algorithm>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 const int INF = 0xfffffff;
 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)
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("hdoj1233.txt", "r", stdin);
45     while (scanf("%d", &n) == 1 && n)
46     {
47         memset(map, 0, sizeof(map));
48         int a, b, c;
49         int nums = n*(n - 1) / 2;
50         for (int i = 0; i < nums; i++)
51         {
52             scanf("%d%d%d", &a, &b, &c);
53             map[a][b] = c;
54             map[b][a] = c;
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 = 5000;
20 int p[N];    //并查集使用
21 vector<Edge> v;
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("hdoj1233.txt", "r", stdin);
52     while (scanf("%d", &n) == 1 && n)
53     {
54         int a, b, d;
55         int nums = n*(n - 1) / 2;
56         v.clear();
57         for (int i = 0; i < nums; i++)
58         {
59             scanf("%d%d%d", &a, &b, &d);
60             v.push_back(Edge(a, b, d));
61         }
62         kruskal();
63     }
64 }

注意点

在Prime算法和Kruskal算法的开始都定义了一个常量N,但N的含义有所不同:Prime算法中的N是结点的最大数目,Kruskal算法中的N是边的最大数目。

以上是关于hdoj1233 还是畅通工程(Prime || Kruskal)的主要内容,如果未能解决你的问题,请参考以下文章

hdoj1879 继续畅通工程(Prime || Kruskal)

HDU 1233 还是畅通工程

还是畅通工程[HDU1233]

hdu-1233 还是畅通工程

HDU 1233: 还是畅通工程

hdu 1233 还是畅通工程 (prim)