poj1251 Jungle Roads(Prime || Kruskal)
题目链接
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 }
本站使用「CC BY-NC-SA」创作共享协议,转载请在文章明显位置注明作者及出处。