zoukankan      html  css  js  c++  java
  • 1408E.Avoid Rainbow Cycles(最大生成树)

    给定m套整数A1,A2,…,Am;这些集合的元素是1到n之间(包括1和n)的整数。

    有两个正整数数组a1,a2,...,am和b1,b2,...,bn。

    在一个操作中,您可以从集合Ai中删除元素j,并为此支付ai + bj硬币。

    您可以执行几个(也许没有)操作(某些集合可能为空)。

    在那之后,您将制作一个由n个顶点组成的边色无向图。对于每个集合Ai,您将为所有x,y∈Ai和x <y添加一条颜色为i的边(x,y)。某些顶点对可以连接多个边,但是这些边具有不同的颜色。

    如果其上所有边的颜色都不同,则称为循环i1→e1→i2→e2→…→ik→ek→i1(ej是连接顶点ij和ij + 1的某些边)。

    找出要获得没有彩虹周期的图表所需的最小硬币数量。

    题解:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e5+100;
    typedef long long ll;
    struct node {
        int u,v;
        ll w;
        bool operator < (const node &r) const {
            return w>r.w;
        }
    }edge[maxn<<2];
    int n,m;
    ll a[maxn];
    int father[maxn];
    int findfather (int x) {
        int a=x;
        while (x!=father[x]) x=father[x];
        while (a!=father[a]) {
            int z=a;
            a=father[a];
            father[z]=x;
        }
        return x;
    }
    int main () {
        ll ans=0;
        int tot=0;
        scanf("%d%d",&m,&n);
        for (int i=1;i<=n+m;i++) scanf("%lld",a+i),father[i]=i;
        for (int i=1;i<=m;i++) {
            int k;
            scanf("%d",&k);
            for (int j=1;j<=k;j++) {
                int x;
                scanf("%d",&x);
                ll v=a[i]+a[m+x];ans+=v;
                edge[++tot]={i,m+x,v};
            }
        }
        sort(edge+1,edge+tot+1);
        for (int i=1;i<=tot;i++) {
            int x=edge[i].u;
            int y=edge[i].v;
            x=findfather(x);
            y=findfather(y);
            if (x==y) continue;
            ans-=edge[i].w;
            father[y]=x;
        }
        printf("%lld
    ",ans);
    }
  • 相关阅读:
    Nginx 高级配置
    nginx安装和优化配置
    location语法介绍
    iptables
    通过 loganalyzer 展示数据库中的系统日志
    ubuntu_server16.04详细安装步骤
    内存控制mmap的原型和使用方法
    C语言中open函数read函数lseek函数是如何使用的
    gdb调试工具的基本使用
    C语言如何制作静态库
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14352629.html
Copyright © 2011-2022 走看看