1. 程式人生 > >hdoj1233 還是暢通工程(Prime || Kruskal)

hdoj1233 還是暢通工程(Prime || Kruskal)

() find set main namespace ref min ons 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)