POJ 3522 (生成树)

题目链接:http://poj.org/problem?id=3522

题意: 求一棵生成树, 使得生成树的最大边权与最小边权的差值最小。

思路: 按边权从小到大 依次枚举生成的最小生成树, 求最小差值即可。

AC代码:

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

 

你可能感兴趣的:(#,生成树)