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是边的最大数目。

时间: 2024-10-13 01:59:54

hdoj1233 还是畅通工程(Prime || Kruskal)的相关文章

hdu 1875 畅通工程再续(Kruskal算法)

题目来源:hdu 1875 畅通工程再续 畅通工程再续 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 20477 Accepted Submission(s): 6453 Problem Description 相信大家都听说一个"百岛湖"的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政

HDU 1875 畅通工程再续 (Kruskal + hash)

畅通工程再续 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 16453    Accepted Submission(s): 5108 Problem Description 相信大家都听说一个"百岛湖"的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先

hdu 1233 还是畅通工程(kruskal求最小生成树)

还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 31362    Accepted Submission(s): 14083 Problem Description 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路

HDU 1879--继续畅通工程【kruskal &amp;&amp; 最小生成树 &amp;&amp; 水题】

继续畅通工程 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 17798    Accepted Submission(s): 7662 Problem Description 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).现得到城镇道路统计表,表中列

畅通工程(kruskal算法)

个人心得:日了狗,WR了俩个小时才发现是少了个vector清理,我也是醉了,不过后面还是对这个有了更好得了解,一是我得算法,而是学长改进 后的算法,改进后得算法还要判断所有村庄是否在连在一起,其实我觉得实必要性不大. 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本.现请你编写程序,计算出全省畅通需要的最低成本. Input 测试输入包含若干测试用

[HDOJ1233]还是畅通工程

还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 30793    Accepted Submission(s): 13822 Problem Description 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能

HDU1879:继续畅通工程【kruskal】

继续畅通工程 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 17839    Accepted Submission(s): 7681 Problem Description 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).现得到城镇道路统计表,表中列

hdu 1233 还是畅通工程(prim||kruskal)

这个完完全全就是模板题目,没有一点变化,就是单纯的让求最小生成树 代码:(prim) #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<vector> #include<set> #include<queue> #include<string> #inclu

hdu 1875 畅通工程再续(kruskal)

这道题目有点变化,条件是每条路的花费不能超过1000也不能小于10,否则不修该条路,所以呢,用kruskal最好,这种方法是检查每一条边,符合情况就加进去,否则就舍去,这样最后判断一下是不是所有的点都有一个共同的祖先就知道是不是连通图.如果用prim算法的话,它每次选的是最小值,得判断一下,实现起来比较麻烦. 代码:(kruskal) #include<iostream> #include<cstdio> #include<cstdlib> #include<cs