欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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;
}

 

相关标签: 生成树