Slim Span UVALive - 3887
图论·生成树
题目大意:
求一棵最大边-最小边的值最小的生成树。
题解:
把边排序,枚举最小的,kruskal加边,当图第一次连通的时候当前的边就是尽可能小的最大边,更新答案即可。
Code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 105;
const int M = 10005;
const int INF = 0x3f3f3f3f;
int n,m,ans;
struct Edge{
int u,v,w;
bool operator < (const Edge & tp) const {
return w < tp.w;
}
}e[M];
int pa[N];
void init(){ for(int i=1;i<=n;i++)pa[i]=i; }
int find(int x){
if(x!=pa[x]) pa[x]=find(pa[x]);
return pa[x];
}
bool solve(int s){
init(); int cnt=0,i;
for(i=s;i<=m;i++){
int xx=find(e[i].u), yy=find(e[i].v);
if(xx!=yy){
pa[xx]=yy;
if(++cnt==n-1) break;
}
}
if(cnt==n-1){
ans=min(ans,e[i].w-e[s].w);
return true;
}
else return false;
}
int main(){
freopen("a.in","r",stdin);
while(~scanf("%d%d",&n,&m) && (n||m)){
for(int i=1;i<=m;i++){
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
}
sort(e+1,e+1+m);
ans=INF;
for(int i=1;i<=m;i++){
if(!solve(i)) break;
}
if(ans==INF) ans=-1;
printf("%d\n",ans);
}
}

本文介绍了一种求解特定生成树问题的算法——寻找一棵无向带权图中的生成树,使得该生成树上最大边与最小边之差最小。通过先对所有边进行排序,再使用Kruskal算法来确定生成树的方法,实现了一种高效的解决方案。
122

被折叠的 条评论
为什么被折叠?



