题意翻译
求所有生成树中最大边权与最小边权差最小的,输出它们的差值。
输入:
输入文件包含多组测试数据,每组测试数据如下: 第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;
}