最小生成树 之 kruskal 算法 Jungle Roads POJ - 1251

原题

      Jungle Roads


地图显示了现在使用的所有道路以及每月维护这些道路的费用。他们每个月能花多少钱,维护连接所有村庄的道路。这些村庄在上面的地图上标着 A 到 I。右边的地图显示了最便宜的道路,每月216个  aacms(货币单位,我也不知道哪国的)。

输入

输入由一到100个数据集组成,最后一行只包含0。每个数据集开始时只包含一个数字n,即村庄数,1

输出量

每个数据集的输出为每一行一个整数:每个月用于维护连接所有村庄的公路系统的最低成本。

样本输入

9
A 2 B 12 I 25
B 3 C 10 H 40 I 8
C 2 D 18 G 55
D 1 E 44
E 2 F 60 G 38
F 0
G 1 H 35
H 1 I 35
3
A 2 B 10 C 40
B 1 C 20
0

样本输出

216
30

题意: 在所有道路中选取权值最小的道路,组成一个通路

解题思路: 将每条边的权值最小的按从小到大排序,将那条边所涉及的点归并为一个集合,                       用并查集思想。

#include
#include
#include
using namespace std;
int fa[35];
int m;
struct node{
	int s;	  // 起始点 
	int e;	 // 终止点 
	int w;    // 权值,也就是道路的维修费 
}a[505];
bool cmp(node a,node b){   // 将结构体中权值按从小到大排序  
   return a.w < b.w;
}
int get(int i){       // 此处并查集,必须进行路径压缩 
   if(fa[i] != i){
		fa[i] = get(fa[i]);
	}
	return fa[i];
}
void kruskal(){
	sort(a,a+m,cmp);
	int ans = 0;
	for(int i = 0;i < m;i++){   // 循环将起始点和终止点压缩进一个集合 
		int x = get(a[i].s);
		int y = get(a[i].e);
		if(x != y){
			fa[x] = y;
			ans += a[i].w;   // 计算求和 
		}
	}
	printf("%d\n",ans);
}
int main(){
	int n;
	while(scanf("%d",&n) && n){
		char ch1,ch2;
		int x,y;
		for(int i = 0;i < n;i++){
			fa[i] = i;
		}
		m = 0;n--;
		while(n--){
			cin >> ch1 >> x;
			while(x--){
				cin >> ch2 >> y;
				a[m].s = ch1 - 'A';  // 将字母转换为数字,便于管理 
				a[m].e = ch2 - 'A';
				a[m].w = y;
				m++;
			}
		}
		kruskal();
	}
	return 0;
} 

 新手,写得不好;大神如果觉得不好,还请多多指教,悉心接受教诲;

  有看不懂的留言评论我会回复;

 

你可能感兴趣的:(最小生成树)