题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4141
题意:求一个图最大边减最小边最小的生成树
思路:n=100,所以把边排序,从小到大枚举小的边,每次枚举都使点都连接,最后选最小的就行了。
代码:
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 1e2 + 5;
const int mod = 1e9 + 7;
int n, m, p[maxn];
struct edge {
int u, v, cost;
} e[5005];
bool cmp(edge a, edge b) {
return a.cost > b.cost;
}
void init(int n) {
for (int i = 0; i <= n; i++) p[i] = i;
}
int Find(int x) {
return p[x] == x ? x : (p[x] = Find(p[x]));
}
int kruskal(int l) {
int ans;
int Min=INF,Max=0;
init(n);
for (int i = l; i < m; i++) {
int u = e[i].u, v = e[i].v;
int x = Find(u);
int y = Find(v);
if (x != y) {
Min=min(Min,e[i].cost);
Max=max(Max,e[i].cost);
p[x] = y;
}
}
ans=Max-Min;
int x=Find(1);
for (int i=2;i<=n;i++){
if (Find(i)!=x) {
ans=-1;
break;
}
}
return ans;
}
int main () {
while (~scanf ("%d%d",&n,&m)&&n){
for (int i=0;i<m;i++){
scanf ("%d%d%d",&e[i].u,&e[i].v,&e[i].cost);
}
sort(e,e+m,cmp);
int ans=INF;
for (int i=0;i<m;i++){
int x=kruskal(i);
if (x==-1) continue;
ans=min(ans,x);
}
if (ans!=INF){
printf ("%d\n",ans);
}
else printf ("-1\n");
}
return 0;
}