poj1251 Jungle Roads(Prime || Kruskal)
阿新 • • 發佈:2017-12-03
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 7const 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)