[题解] uva 1395 slim span(kruskal最小生成树)

- 传送门 -

 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4141

#1395 - Slim Span

Time limit: 3.000 seconds

| Root | Submit Problem Stats
uDebug Download as PDF |

(题面见pdf)

 

- 题意 -

 求一棵最大边与最小边差值最小的生成树.
 

- 思路 -

 边按权值排序, 然后直接枚举.
 枚举从第 k 大的边开始插入, 然后依次插入比它大的边, 当插入的边生成了树时, 当前边和最开始插入的边的差值就可以用来更新答案了.
 
 细节见代码.
 

- 代码 -

#include<cstdio>
#include<algorithm>
using namespace std;

const int N = 105;
const int INF = 1e9;

struct edge {
	int x, y, v;
}W[N*N*2];

int F[N];
int n, m, ans, cnt;

bool cmp (edge a, edge b) { return a.v < b.v; }

int find(int x) { return x == F[x] ? x : F[x] = find(F[x]); }

void add(int t) {
	int xf = find(W[t].x), yf = find(W[t].y);
	if (xf == yf) return;
	F[xf] = yf;
	cnt ++;
}

int main() {
	while ((scanf("%d%d", &n, &m) != EOF) && n) {
		for (int i = 1; i <= m; ++i)
			scanf("%d%d%d", &W[i].x, &W[i].y, &W[i].v);
		sort(W + 1, W + m + 1, cmp);
		ans = INF;
		for (int i = 1; i <= m - n + 2; ++i) {
			for (int j = 1; j <= n; ++j)
				F[j] = j;
			cnt = 0;
			for (int j = i; j <= m; ++j) {
				add(j);
				if (cnt == n - 1) {
					ans = min(ans, W[j].v - W[i].v);
					break;
				}
			}
		}
		if (ans == INF) ans = -1;
		printf("%d
", ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Anding-16/p/7354020.html