码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3522 Slim Span(最小生成树)

时间:2015-08-28 21:40:04      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:poj   最小生成树   

题意:给定一个n个点m条边的无向图,找一颗苗条度(最大边减最小边)最小的生成树。

思路:假设苗条度最小的这棵树的最小边为a,若要使苗条度最小,答案一定是以a为最小边的一颗最小生成树,所以可以考虑枚举最小边,计算出苗条度并更新答案。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#define eps 1e-6
#define LL long long
using namespace std;

const int maxn = 100 + 5;
const int maxm = 10000;
const int INF = 0x3f3f3f3f;
int n, m;
int u[maxm], v[maxm], w[maxm], p[maxn], r[maxm];
bool cmp(const int i, const int j) {
	return w[i] < w[j];
} 
int find_p(int x) {
	return p[x] == x ? x : p[x] = find_p(p[x]);
}
int Kruscal(int edge_id) {
	for(int i = 1; i <= n; i++) p[i] = i;
	int cnt = 0;
	for(int i = edge_id; i < m; i++) {
		int e = r[i]; 
		int x = find_p(u[e]), y = find_p(v[e]);
		if(x != y) {
			p[x] = y;
			cnt++;
		}
		if(cnt == n-1) return w[e]-w[r[edge_id]]; 
	}
	return INF;
}
int main() {
	//freopen("input.txt", "r", stdin);
	while(cin>>n>>m && n) {
		for(int i = 0; i < m; i++) scanf("%d%d%d", &u[i], &v[i], &w[i]);
		for(int i = 0; i < m; i++) r[i] = i;
		sort(r, r+m, cmp);
		int ans = INF;
		for(int i = 0; i < m; i++) ans = min(ans, Kruscal(i));
		if(ans == INF) ans = -1;
		cout << ans << endl; 
	}
	return 0;
}






版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ 3522 Slim Span(最小生成树)

标签:poj   最小生成树   

原文地址:http://blog.csdn.net/u014664226/article/details/48056509

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!