加载中…
个人资料
JosiahChiu
JosiahChiu
  • 博客等级:
  • 博客积分:0
  • 博客访问:7,096
  • 关注人气:87
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

POJ 3552 生成树中最大边-最小边 最小

(2010-09-26 21:02:26)
标签:

poj

3552

生成树

it

分类: 图论

题目描述:如题。

解题报告:枚举(不是二分)最小边,求得的最小生成树的最大边减去这个最小。

所有答案中最小值就是答案。

代码如下:

#include<iostream>
#include<algorithm>
using namespace std;
int cnt, n, m, fa[101];
struct pint
{
    int from, to, val;
    friend bool operator < (pint a, pint b){return a.val < b.val;}
}x[10000];
int find(int id)
{
    if (fa[id] == -1) return id;
    return fa[id] = find(fa[id]);
}
void merge(int a, int b)
{
    int aa = find(a), bb = find(b);
    if (aa != bb) fa[aa] = bb;
}
int jeogia(int from, int n, int m)
{
    memset(fa, -1, sizeof(int) * (n + 1));
    int sta = from;
    int mmin = 0x7fffffff, mmax = -1;
    for(int i = 1; i < n; i++)
    {
        while(sta < m)
            if (find(x[sta].from) != find(x[sta].to)) break;
            else sta++;
        if (sta >= m) return -1;
        merge(x[sta].from, x[sta].to);
        mmin = min(mmin, x[sta].val); mmax = max(mmax, x[sta].val); sta++;
    }
    return mmax - mmin;
}
int main()
{
    while(scanf("%d%d", &n, &m) && (n || m))
    {
        for(int i = 0; i < m; i++)
            scanf("%d%d%d", &x[i].from, &x[i].to, &x[i].val);
        sort(x, x + m);
        if (m < n - 1) {printf("-1\n"); continue;}
        int l = 0, r = m - (n - 1), ans = 0x7fffffff;
        while(l <= r)
        {
            int tmp = jeogia(l, n, m); l++;
            if (tmp != -1) ans = min(ans, tmp);
        }
        if (ans == 0x7fffffff) printf("-1\n");
        else printf("%d\n", ans);
    }
    return 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有