1. 程式人生 > >poj1251 Jungle Roads(Prime || Kruskal)

poj1251 Jungle Roads(Prime || Kruskal)

const blank fff tdi ron 路徑 str pre string

題目鏈接

http://poj.org/problem?id=1251

題意

有n個村莊,村莊之間有道路連接,求一條最短的路徑能夠連接起所有村莊,輸出這條最短路徑的長度。

思路

最小生成樹問題,使用普利姆算法(Prime)或者克魯斯卡爾算法(Kruskal)解決。

代碼

Prime算法:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6 
 7
const int INF = 0xfffffff; 8 const int N = 30; 9 int n; 10 int jungle[N][N]; 11 int dist[N]; //記錄從起點到其余各點的距離並不斷更新 12 13 int prime() 14 { 15 int min_edge, min_node; 16 for (int i = 0; i < n; i++) 17 dist[i] = INF; 18 int now = 0; 19 int ans = 0; 20 for (int i = 0
; i < n - 1; i++) 21 { 22 dist[now] = -1; //標記結點now+‘A‘被訪問過了 23 min_edge = INF; 24 for (int j = 0; j < n; j++) 25 { 26 if (j != now && dist[j]>=0) 27 { 28 if (jungle[now][j]>0) 29 dist[j] = min(dist[j], jungle[now][j]);
30 if (dist[j] < min_edge) 31 { 32 min_edge = dist[j]; //選取從當前結點到其余各點的最短路徑 33 min_node = j; 34 } 35 } 36 } 37 now = min_node; 38 ans += min_edge; //當前最小生成樹的長度 39 } 40 return ans; 41 } 42 43 int main() 44 { 45 //freopen("poj1251.txt", "r", stdin); 46 while (cin >> n && n) 47 { 48 memset(jungle, 0, sizeof(jungle)); 49 for (int i = 0;i < n-1;i++) 50 { 51 char p, q; 52 int v, w; 53 cin >> p >> v; 54 for (int j = 0;j < v;j++) 55 { 56 cin >> q >> w; 57 jungle[p - A][q - A] = w; 58 jungle[q - A][p - A] = w; 59 } 60 } 61 int ans = prime(); 62 cout << ans << endl; 63 } 64 return 0; 65 }

Kruskal算法:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6 
 7 const int N = 100;
 8 int s[N], e[N], v[N];    //分別存儲每一條路的起點、終點、長度
 9 int p[N];    //並查集使用
10 int n;
11 int cnt;    //存儲有多少條路
12 
13 bool cmp(int i, int j)
14 {
15     return v[i] < v[j];
16 }
17 
18 int find_root(int x)
19 {
20     if (p[x] == -1)
21         return x;
22     else return find_root(p[x]);
23 }
24 
25 int kruskal()
26 {
27     memset(p, -1, sizeof(p));
28     int r[N];
29     for (int i = 0; i < cnt; i++)
30         r[i] = i;
31     sort(r, r + cnt, cmp);    //根據路徑長度v[]的大小對數組r[]排序
32     int ans = 0;
33     for (int i = 0; i < cnt; i++)
34     {
35         int cur = r[i];
36         int a = find_root(s[cur]);
37         int b = find_root(e[cur]);
38         if (a != b)
39         {
40             ans += v[cur];
41             p[a] = b;
42         }
43     }
44     return ans;
45 }
46 
47 int main()
48 {
49     //freopen("poj1251.txt", "r", stdin);
50     while (cin >> n && n)
51     {
52         cnt = 0;
53         char p, q;
54         int nums, w;
55         for (int i = 0; i < n - 1; i++)
56         {
57             cin >> p >> nums;
58             for (int j = 0; j < nums; j++)
59             {
60                 cin >> q >> w;
61                 s[cnt] = p - A;
62                 e[cnt] = q - A;
63                 v[cnt] = w;
64                 cnt++;
65             }
66         }
67         int ans = kruskal();
68         cout << ans << endl;
69     }
70     return 0;
71 }

poj1251 Jungle Roads(Prime || Kruskal)