第五十三题 UVA1395 苗条的生成树 Slim Span ACM/ICPC Japan 2007

PDF

题意翻译

求所有生成树中最大边权与最小边权差最小的,输出它们的差值。

输入:

输入文件包含多组测试数据,每组测试数据如下: 第1行:2个整数n m (2 ≤ n ≤ 100 and 0 ≤ m ≤ n(n − 1)/2),n表示顶点数,m表示边数。接下来m行,每行3个空格分开的整数a b w(1 ≤ w ≤ 10000) , 表示顶点a与顶点b之间有一条边,权值为w。

输出:

对每组测试数据,如果图存在生成树,输出生成树的差值最小的;否则,输出-1。

终于还是来到了我最喜欢的图论部分(其实是眼睛肿了,想赶紧水几个题然后休息去,今天还有喜欢的广东打山东emmmmmmmm)
本来一看这个题还挺难的,然而!!! 保留Kruskal 根本不用考虑时间复杂度

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define Maxn 102
#define Maxm 10002
using namespace std;

const int INF = 0x3f3f3f3f;
struct Edge{
	int u,v,w;
	bool operator < (const Edge &a ) const {
		return w < a.w;
	}
}e[Maxm];
int fa[Maxn];

int Find(int x) {
	if(fa[x] == x) return x;
	else return fa[x] = Find(fa[x]);
} 

int main(int argc,char* argv[]) {
	int n,m;
	while(scanf("%d %d",&n,&m) == 2 && n) {
		for(int u,v,w,i=1; i<=m; i++) {
			scanf("%d %d %d",&u,&v,&w);
			e[i].u = u,e[i].v = v,e[i].w = w;
		}
		sort(e + 1, e + m + 1);
		int L = 1,R,Ans = INF,Num = 0;
		Ans = INF;
		while(L <= m - n + 2) {
			Num = 0;
			for(int i=1; i<=n; i++) fa[i] = i;
			
			for(int i=L; i<=m; i++) {
				int u = e[i].u,v = e[i].v,w = e[i].w;
				int fu = Find(u),fv = Find(v);
				if(fu == fv) continue;
				fa[fu] = fv; Num ++;
				if(Num == n-1) {
					R = i;
					Ans = min(Ans,e[R].w - e[L].w);
					break;
				}
			}
			L++;
			if(Ans == INF) { Ans = -1; break; }
		}
		if(n >= m + 2) Ans = -1;
		printf("%d\n",Ans);
	}
	
	
	return 0;
}
发布了732 篇原创文章 · 获赞 31 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/qq_35776409/article/details/104033738