原题
地图显示了现在使用的所有道路以及每月维护这些道路的费用。他们每个月能花多少钱,维护连接所有村庄的道路。这些村庄在上面的地图上标着 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<cstdio>
#include<algorithm>
#include<iostream>
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;
}
新手,写得不好;大神如果觉得不好,还请多多指教,悉心接受教诲;
有看不懂的留言评论我会回复;