zoukankan      html  css  js  c++  java
  • poj3522

    题意:给点一个无向图,求一个生成树使树中最大边与最小边的差的最小。

    分析:并查集。把所有边排序,然后从小到大看,每次枚举一个边,将其权值作为下界,向右寻求一个上界,让上下界之间的边可以使得图连通。寻求过程中,是每次将一个边加入图中,判断图是否连通,不行则再加一条边,判断过程用并查集。找到没个下界对应的上界,找上下界差的最小值。

    View Code
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int maxn = 105, maxm = maxn * maxn / 2, inf = 0x3f3f3f3f;
    
    struct Edge
    {
        int a, b, w;
    }edge[maxm];
    
    int n, m;
    int father[maxn];
    
    bool operator < (const Edge &a, const Edge &b)
    {
        return a.w < b.w;
    }
    
    void input()
    {
        for (int i = 0; i < m; i++)
        {
            int a, b, w;
            scanf("%d%d%d", &a, &b, &w);
            a--;
            b--;
            edge[i].a = a;
            edge[i].b = b;
            edge[i].w = w;
        }
    }
    
    int getanc(int a)
    {
        if (a == father[a])
            return a;
        return father[a] = getanc(father[a]);
    }
    
    int cal(int l)
    {
        for (int i = 0; i < n; i++)
            father[i] = i;
        int i = l;
        int block_num = n;
        while (i < m && block_num > 1)
        {
            int a = getanc(edge[i].a);
            int b = getanc(edge[i].b);
            if (a != b)
            {
                block_num--;
                father[a] = b;
            }
            i++;
        }
        if (block_num > 1)
            return -1;
        return edge[i - 1].w - edge[l].w;
    }
    
    void work()
    {
        int ans = cal(0);
        if (ans == -1)
        {
            printf("-1\n");
            return;
        }
        for (int i = 1; i < m; i++)
        {
            if (edge[i].w == edge[i - 1].w)
                continue;
            int temp = cal(i);
            if (temp == -1)
                break;
            ans = min(ans, temp);
        }
        printf("%d\n", ans);
    }
    
    int main()
    {
        //freopen("t.txt", "r", stdin);
        while (scanf("%d%d", &n, &m), n | m)
        {
            memset(edge, -1, sizeof(edge));
            input();
            sort(edge, edge + m);
            work();
        }
        return 0;
    }
  • 相关阅读:
    iOS 之 创建分类
    iOS 之 动画
    iOS 倒出spa文件 打包
    js闭包
    wampserver配置多站点
    js重定向
    php obstart
    php保存远程图片
    php获取前天的昨天的日期
    weixin js接口
  • 原文地址:https://www.cnblogs.com/rainydays/p/2574314.html
Copyright © 2011-2022 走看看