题意:给定一个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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u014664226/article/details/48056509