POJ 3522 (生成树)
程序员文章站
2024-03-21 17:23:34
...
题目链接:http://poj.org/problem?id=3522
题意: 求一棵生成树, 使得生成树的最大边权与最小边权的差值最小。
思路: 按边权从小到大 依次枚举生成的最小生成树, 求最小差值即可。
AC代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<set>
using namespace std;
const int maxn = 105;
int fa[maxn];
struct xx{
int l,r,w;
xx(){}
xx(int l,int r,int w):l(l),r(r),w(w){}
}edge[maxn*50];
bool cmp(xx A, xx B){
return A.w < B.w;
}
int _find(int x){
if(fa[x] == x) return x;
return fa[x] = _find(fa[x]);
}
int maxx = -1,minn = 1e9,coun = 0;;
void _union(int x,int y,int w){
int fx = _find(x),fy = _find(y);
if(fx != fy){
maxx = max(maxx,w);
minn = min(minn,w);
fa[fx] = fy;
coun ++;
}
}
void init(){
for(int i = 0;i < maxn;i ++) fa[i] = i;
maxx = -1; minn = 1e9; coun = 0;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m)){
if(!n && !m) break;
int a,b,w;
for(int i = 0;i < m;i ++){
scanf("%d%d%d",&a,&b,&w);
edge[i] = xx(a,b,w);
}
sort(edge,edge + m,cmp);
int MIN = 1e9;
int flag = 0,flag1 = 0;;
for(int i = 0;i < m;i ++){
init(); flag1 = 0;
for(int j = i;j < m;j ++){
_union(edge[j].l,edge[j].r,edge[j].w);
if(coun == n - 1){
flag = 1; flag1 = 1;
break;
}
}
if(flag1 == 0) break;
MIN = min(MIN,maxx - minn);
}
if(!flag) printf("-1\n");
else printf("%d\n",MIN);
}
return 0;
}