您的位置:首页 > 其它

UVA-1395 Slim Span

2015-04-20 22:37 169 查看
一道简单的图论题(并查集+Kruskal)
求一个图的的生成树,要求最大边减最小边之差最小,输出权值之差,如果没有,输出-1
要求权值差最小,所以首先将边按权值排序,枚举最小边,对于每个最小边从小到大枚举最大边
用并查集判断是否连通,如果可以生成树更新ans

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define inf 0x7f7f7f7f
#define rep(i,n) for(int (i)=0;(i)<(n);i++)
#define ABS(x,y) (x-y>0)?(x-y):(y-x)
#define mem(a) memset(a,0,sizeof(a));
#define in(a) cin>>a
#define out(a) cout<<a
const int maxn=110;
struct Edge
{
int u;
int v;
int w;
Edge(int u,int v,int w):u(u),v(v),w(w){}
};
int n,m; int p[maxn];
int cmp(const Edge& a,const Edge& b){
return a.w<b.w;
}
int find(int x){
return p[x]==x?x:p[x]=find(p[x]);
}
int main()
{   //freopen("input.txt","r",stdin);
while(scanf("%d%d", &n, &m) == 2 && (n || m)){
vector<Edge> e; int u,v,w;
for(int i=0;i<m;i++){
scanf("%d%d%d", &u, &v, &w);
e.push_back(Edge(u,v,w));
}
sort(e.begin(),e.end(),cmp);
int ans=inf; int sign=0;
for(int L=0;L<e.size();L++){
for(int i=0;i<=n;i++) p[i]=i;
int cnt=0; int beg=e[L].w;
int end=beg;
for(int R=L;R<e.size();R++){
int x=find(e[R].u);;int y=find(e[R].v);
if(x!=y){
++cnt;
p[x]=y;
end=max(end,e[R].w);
}
if(cnt==n-1) break;
}
if(cnt==n-1){
sign=1;
ans=min(ans,end-beg);
}
}
if(sign==1) printf("%d\n", ans);
else printf("-1\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: