zoukankan      html  css  js  c++  java
  • 构造完全图

    https://loj.ac/problem/10067

    题目描述

      给出一棵最小生成树,求有且仅有这一棵最小生成树的总边权最小的完全图。

    思路

      我们考虑对于最小生成树中的一条边,它一定连接着两个连通支(T1,T2),并且是连通(T1、T2)的边中边权最小的,而我们构造完全图时,一定要将(T1、T2)中的节点两两连边,而显然除了最小生成树中的边(设其边权为(v))其余边权均为(v+1)时边权最小。所以我们可以记录每个连通支中的节点数,进行一次(Kruskal),在合并两个连通支时统计答案即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=1e5+10;
    struct Edge
    {
        int x,y,d;
    }e[MAXN];
    int fa[MAXN],siz[MAXN];
    int find(int x)
    {
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    bool cmp(Edge x,Edge y)
    {
        return x.d<y.d;
    }
    int main() 
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<n;i++)
            scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].d);
        for(int i=1;i<=n;i++)
            fa[i]=i,siz[i]=1;
        sort(e+1,e+n,cmp);
        long long sum=0;
        int cnt=0;
        for(int i=1;i<n;i++)
        {
            int fx=find(e[i].x),fy=find(e[i].y);
            if(fx!=fy)
            {
                fa[fx]=fy;
                sum+=(long long)(siz[fx]*siz[fy]-1)*(e[i].d+1);
                sum+=e[i].d;
                siz[fy]+=siz[fx];
                cnt++;
                if(cnt==n-1)break ;
            }
        }
        printf("%lld",sum);
        return 0;
    }
    
  • 相关阅读:
    Spark API 之 map、mapPartitions、mapValues、flatMap、flatMapValues详解
    大三寒假生活9
    大三寒假生活8
    大三寒假生活7
    MySQL SQL DML (数据操作语言)
    MySQL JOIN
    Python 可执行对象
    Python __slots__
    Python tempfile (临时文件)
    Python 文件操作
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11794812.html
Copyright © 2011-2022 走看看