• Codeforces Round #535 F-MST Unification


    题目大意:

    给定n m 为图中的点数n和边数m

    给定m条边的信息 u v w 为u点到v点有一条长度为w的边

    图中无环无重边

    这个图的MST的花费为k 但可能存在多种花费为k的MST的方案

    此时对图中的边进行操作 可增大权重或翻倍增大权重

    要求只保留图中的一种花费为k的MST方案时 需要对最少多少条边进行操作

    1.原本的kruskal 会选出构成MST的最短的n-1条边

    即在n=5边长度为 1 2 2 3 4 4 5 6 的图中

    原本会选出4条 1 2 3 4 (能构成1种MST的方案)

    2.这个方法会记录到最短的n-1条边和与这些边长度相等的边

    现在会选出6条 1 2 2 3 4 4 (能构成多种MST方案)

    3.此时只保留一种MST方案的话需4条(n-1条)边

    则需要对多出的6-4=2条边进行操作

    #include <bits/stdc++.h>
    #define INF 0x3f3f3f3f
    #define LL long long
    using namespace std;
    const int N=2e5+5;
    int n, m;
    struct EDGE {
        int u,v,w;
        bool operator <(const EDGE& p)const {
            return w<p.w;
        }
    }e[N];
    int fa[N];
    int getfa(int u) {
        if(fa[u]==u) return u;
        else return fa[u]=getfa(fa[u]);
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m)) {
            for(int i=0;i<m;i++)
                scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
            sort(e,e+m);
            for(int i=1;i<=n;i++) fa[i]=i;
            int ans=0, L=0;
            for(int i=0;i<m;i++) {
                int u=getfa(e[i].u), v=getfa(e[i].v);
                if(u!=v) ans++;
    
                if(i+1<m and e[i+1].w!=e[i].w) {
                    for(int j=L;j<=i;j++) {
                        u=getfa(e[j].u), v=getfa(e[j].v);
                        if(u!=v) fa[u]=v;
                    }
                    L=i+1;
                }
            }
            printf("%d
    ",ans-(n-1));
            /// 去掉唯一的的MST所需的n-1条边
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    概率算法实现八皇后问题-cpp
    交互式多媒体图书平台的设计
    Map容器
    序列容器和容器适配器
    ubuntu18.04 基于VSCode的C++环境搭建
    工程化编程实战callback接口学习
    stl_string
    通过filebeat的modules搜集nginx日志
    gitlab-runner安装配置
    EFK搜集MySQL慢日志
  • 原文地址:https://www.cnblogs.com/zquzjx/p/10312490.html
Copyright © 2020-2023  润新知