zoukankan      html  css  js  c++  java
  • 进阶实验6-3.6 最小生成树的唯一性 (35分)

    给定一个带权无向图,如果是连通图,则至少存在一棵最小生成树,有时最小生成树并不唯一。本题就要求你计算最小生成树的总权重,并且判断其是否唯一。

    输入格式:

    首先第一行给出两个整数:无向图中顶点数 N(≤)和边数 M。随后 M 行,每行给出一条边的两个端点和权重,格式为“顶点1 顶点2 权重”,其中顶点从 1 到N 编号,权重为正整数。题目保证最小生成树的总权重不会超过 230​​。

    输出格式:

    如果存在最小生成树,首先在第一行输出其总权重,第二行输出“Yes”,如果此树唯一,否则输出“No”。如果树不存在,则首先在第一行输出“No MST”,第二行输出图的连通集个数。

    输入样例 1:

    5 7
    1 2 6
    5 1 1
    2 3 4
    3 4 3
    4 1 7
    2 4 2
    4 5 5
    
     

    输出样例 1:

    11
    Yes
    
     

    输入样例 2:

    4 5
    1 2 1
    2 3 1
    3 4 2
    4 1 2
    3 1 3
    
     

    输出样例 2:

    4
    No
    
     

    输入样例 3:

    5 5
    1 2 1
    2 3 1
    3 4 2
    4 1 2
    3 1 3
    
     

    输出样例 3:

    No MST
    2

    对于最小生成树如果不唯一,那就说明最小生成树中的某条边可以换成其他一条同权值的边且保证仍然是最小生成树,如此只需要对最小生成树中权值不唯一的边进行删除并重新进行最小生成树的查找即可。

    代码:
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    int n,m,c,num;
    struct line {
        int u,v,w;
    }r[130000];
    int f[501],tag[130000],tn,flag;
    void init() {
        for(int i = 1;i <= n;i ++) {
            f[i] = i;
        }
    }
    int getf(int k) {
        return k == f[k] ? f[k] : (f[k] = getf(f[k]));
    }
    bool cmp(const line &a,const line &b) {
        return a.w < b.w;
    }
    bool check() {
        for(int i = 0;i < tn;i ++) {
            init();
            int d = 0,e = 0;
            for(int j = 0;j < m;j ++) {
                if(j == tag[i]) continue;
                if(getf(r[j].u) != getf(r[j].v)) {
                    f[getf(r[j].u)] = getf(r[j].v);
                    d += r[j].w;
                    e ++;
                }
            }
            if(e == n - 1 && d == c) return 1;
        }
        return 0;
    }
    int main() {
        scanf("%d%d",&n,&m);
        init();
        for(int i = 0;i < m;i ++) {
            scanf("%d%d%d",&r[i].u,&r[i].v,&r[i].w);
        }
        sort(r,r + m,cmp);
        for(int i = 0;i < m;i ++) {
            if(getf(r[i].u) != getf(r[i].v)) {
                f[getf(r[i].u)] = getf(r[i].v);
                c += r[i].w;
                if(i < m - 1 && r[i].w == r[i + 1].w || i && r[i].w == r[i - 1].w) {
                    flag = 1;
                    tag[tn ++] = i;
                }
            }
        }
        for(int i = 1;i <= n;i ++) {
            if(getf(i) == i) num ++;
        }
        if(num != 1) printf("No MST
    %d",num);
        else printf("%d
    %s",c,!flag || !check() ? "Yes" : "No");
    }
  • 相关阅读:
    应用开发框架之——业务规则脚本化
    tms脚本演示代码之一
    根据.DFM文件动态生成窗体以及在之前先必须注册窗体中使用到的类
    界面/业务规则脚本化
    delphi 脚本引擎比较
    html5 datalist 选中option选项后的触发事件
    Laravel 5.6 模型关联 user 表后查询 user 表数据只能获取第一条数据,不知道怎么获取第二条...
    小技巧两个感叹号(两个!)连用
    Bootstrap 字体图标(Glyphicons)
    使用withCount后再使用select设置查询的字段。就找不到withCount的数据了
  • 原文地址:https://www.cnblogs.com/8023spz/p/12304948.html
Copyright © 2011-2022 走看看