zoukankan      html  css  js  c++  java
  • 2019.3.16 最小生成树之最平衡生成树

    题目描述
    学习完最小生成树后,老师只给出几道模板题,为了尽快提升自己的编程能力,小C同学给自己出了这样一道题:最平衡生成树。
    最平衡生成树是这样定义的,一个有 n 个结点的连通图的生成树包含原图中的所有n个结点,并且最长边与最短边的差值最小。
    现在给你一个有n个结点的图,求最平衡生成树中最长边与最短边的差值。
    输入
    输入第一行为n和m两个正整数,分别表示图的结点数和边数。
    以下m行每行包含三个数a,b,w,分别表示每条边的两个端点和边的权值。
    输出
    输出满足题目要求的最小值,如果找不到最平衡生成树,则输出-1。
    样例输入
    4 5
    1 2 3
    1 3 5
    1 4 6
    2 4 6
    3 4 7
    样例输出
    1
    提示
    【数据范围】
    对于100%的数据,2<=n<=100,0<=m<=n(n-1)/2,w<=10000。 
    【样例输入2】 
    3 0 
    【样例输出2】 
    -1 

    通过最小生成树的学习我们可以知道 一棵固定起点的最小生成树一定是该点的最平衡生成树
    因为最小生成树要求边权和最小 当固定某起点(即固定该点开头的某条边)时的一棵最小生成树的最大边也最小
    所以我们只需要从小到大枚举每条边为最小边的最小生成树即可
    需要注意的是 当以该边为最小边时若剩余边无法构成最小生成树 则可以直接剪枝跳出循环
    上代码
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int n,m,ans=0x3f3f3f3f,pre[1000005];
    struct edge
    {
        int u,v,w;
        bool operator<(const edge& o) const
        {
            return w<o.w;//重载小于运算符,按照边权排序
        }
    }e[10005];
    int f(int a)//找祖先
    {
        if(pre[a]==a)return a;
        return pre[a]=f(pre[a]);
    }
    void u(int a,int b)//合并
    {
        int c=f(a),d=f(b);
        if(pre[c]!=pre[d])pre[c]=pre[d];
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
        sort(e+1,e+m+1);
        for(int i=1;i<=m;i++)
        {
            int cnt=0,anss=0;//anss为最大边
            for(int j=1;j<=n;j++)pre[j]=j;
            for(int j=i;j<=m&&cnt<n-1;j++)
            {
                int uu=f(e[j].u),vv=f(e[j].v);
                if(f(uu)!=f(vv)) {
                    u(uu,vv);
                    anss=e[j].w;//所有边权按照从小到大排序,故可以每次更新最大边
                    cnt++;
                }
            }
            if(cnt==n-1)ans=min(ans,anss-e[i].w);
            else break;//剪枝,剩余边不足以构成最小生成树
        }
        if(ans==0x3f3f3f3f)puts("-1");//不存在最小生成树
        else printf("%d",ans);
        return 0;
    }
    /*====年轻人,瞎搞是出不了省一的,这就是现实====*/
  • 相关阅读:
    haslayout详解
    linux定时任务-cron
    linux安装SVN
    linux java配置
    KVM virsh常用命令篇
    KVM创建虚拟机
    KVM和远程管理工具virt-manager
    mysql 基础命令
    json在线工具
    mvn简单命令
  • 原文地址:https://www.cnblogs.com/qxds/p/10584204.html
Copyright © 2011-2022 走看看