POJ1251 Jungle Roads (最小生成树&Kruskal)题解

题意:

输入n,然后接下来有n-1行表示边的加边的权值情况。如A 2 B 12 I 25 表示A有两个邻点,B和I,A-B权值是12,A-I权值是25。求连接这棵树的最小权值。

思路:

一开始是在做莫队然后发现没学过最小生成树,就跑过来做模板题了...

Kruskal的使用过程:先按权值大小排序,然后用并查集判断是否能加这条边

Kruskal详解博客:【贪心法求解最小生成树之Kruskal算法详细分析】---Greedy Algorithm for MST


考试周还在敲代码...我...

代码:

#include<queue>
#include<cstring>
#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
const int N = 1e5+5;
const int MOD = 10007;
using namespace std;
struct edge{
	int u,v,value;
	friend bool operator < (edge a,edge b){
		return a.value < b.value;
	}
}e[N];
int fa[30];
int find(int x){
	return fa[x] == x? x : find(fa[x]);
}
int main(){
	int n,u,v,tmp;
	int num;
	char s[2];
	while(scanf("%d",&n) && n){
		num = 0;
		for(int i = 0;i < 30;i++) fa[i] = i;
		for(int i = 1;i <= n-1;i++){
			scanf("%s%d",s,&tmp);
			u = s[0] - 'A';
			for(int j = 1;j <= tmp;j++){
				scanf("%s%d",s,&e[num].value);
				e[num].u = u;
				e[num].v = s[0] - 'A';
				num++;
			}
		}
		sort(e,e+num);
		int ans = 0;
		for(int i = 0;i < num;i++){
			int x = find(e[i].u);
			int y = find(e[i].v);
			if(x != y){
				fa[x] = fa[y];
				ans += e[i].value;
			}
		}
		printf("%d\n",ans);
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_14938523/article/details/80822487
今日推荐