POJ - 1251 Jungle Roads (最小生成树Kruskal、并查集)

来源:互联网 发布:php下载网源码 编辑:程序博客网 时间:2024/05/18 00:10

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

题意:

n个村子,每个村子后面连接各自的邻村、路费,选出使得全部村子相连的最小通路

分析:

n个节点,村子之间的路费为边的权值,Kruskal算法求最小生成树

核心:

void Kruskal(){memset(parent, -1, sizeof(parent));int num = 0, ans = 0, u, v;for(i = 0; i<m; i++){u = edges[i].u; v = edges[i].v;if(Find(u) != Find(v)){ans += edges[i].w;num++;Union(u, v);}if(num >= n-1) break;}printf("%d\n", ans);}


代码:


#include <stdio.h>#include <iostream>#include <string.h>#include <math.h>#include <string>#include <algorithm>#include <queue>#include <stack>#include <map>#include <vector>using namespace std;#define MAXN 30#define MAXM 100#define MIN -1e+10#define INF 0x7f7f7f7fstruct edge{int u, v, w;bool operator < (const edge& p)const{return w<p.w;}}edges[MAXM];int parent[MAXN];int n, m, i, j;int Find(int x){int s, temp;for(s = x; parent[s]>=0; s = parent[s]);while(s != x){temp = parent[x];parent[x] = s;x = temp;}return s;}void Union(int u, int v){int r1 = Find(u), r2 = Find(v);int temp = parent[r1] + parent[r2];if(parent[r1] > parent[r2]){parent[r1] = r2;parent[r2] = temp;}else {parent[r2] = r1;parent[r1] = temp;}}void Kruskal(){memset(parent, -1, sizeof(parent));int num = 0, ans = 0, u, v;for(i = 0; i<m; i++){u = edges[i].u; v = edges[i].v;if(Find(u) != Find(v)){ans += edges[i].w;num++;Union(u, v);}if(num >= n-1) break;}printf("%d\n", ans);}int main(){freopen("a.txt", "r", stdin);char s[2];int nt, w, u, v;while(~scanf("%d", &n) && n){m = 0;for(i = 1; i<n; i++){scanf("%s%d", s, &nt);u = s[0] - 'A' + 1;for(j = 1; j<=nt; j++){scanf("%s%d", s, &w);edges[m].u = u;edges[m].v = s[0] - 'A' + 1;edges[m].w = w;m++;}}sort(edges, edges+m);Kruskal();}return 0;}


0 0