Slim Span UVA - 1395
题意:
给你一个图。要你求生成树。
求苗条度(最大边减最小边的值)尽量小的生成树。
思路:
- 因为n只有100.边只有1000.
- 所以暴力枚举即可。
- 先按照kruskal的套路,先排一下序,之后枚举起点。枚举终点(其实不用,每次求完最小生成树后,都可以 保证最大边减最小边的值尽量小)
AC
#include <iostream>
#include <cstring>
#include <algorithm>
#define fzhead EDGE(int _u, int _v, int _next, int _val)
#define fzbody u(_u), v(_v), next(_next), val(_val)
#define For(i,x,y) for(int i=(x); i<=(y); i++)
#define fori(i,x,y) for(int i=(x); i<(y); i++)
#define mst(x,a) memset(x,a,sizeof(x))
using namespace std;
const int inf=1e9+10;
const int maxn=100+10;
const int maxm=10000+10;
struct EDGE{
int u,v,next,val;
EDGE(){}
fzhead:fzbody{}
bool operator<(const EDGE &a)const {
return val<a.val;
}
}e[maxm];
int head[maxn],tot;
void init(){
mst(head,-1);
tot=0;
}
void add(int bg, int to, int val){
e[tot]=EDGE(bg,to,head[bg],val);
head[bg]=tot++;
}
int n,m;
int f[maxn];
int find(int x){
if(x==f[x])return x;
else return f[x]=find(f[x]);
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
while(cin>>n>>m,n||m){
init();
For(i,1,m){
int u,v,val;
cin>>u>>v>>val;
add(u,v,val);
}
sort(e,e+tot);
int ans=inf;
fori(i,0,tot){
For(j,1,n)f[j]=j;
int cnt=1,mx=0,mi=e[i].val;
fori(j,i,tot){
int A=find(e[j].u),B=find(e[j].v);
if(A==B)continue;
mx=max(e[j].val,mx);
f[A]=B;
cnt++;
if(cnt==n)break;
}
if(cnt==n)ans=min(mx-mi,ans);
}
if(ans!=inf)cout<<ans<<endl;
else cout<<-1<<endl;
}
return 0;
}