• 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);
    }
  • 相关阅读:
    Task级别任务调度分析---源码级
    解决部署K8S集群时flannel无法下载问题
    安装kubernetes+docker集群,一篇文章搞定
    充值-实体类+查询
    充值-controller
    多对一的增删改查-list页面,add页面,update页面,tongji页面
    多对一的增删改查-dao层
    多对一的增删改查-sql语句
    多对一的增删改查-controller
    多对一的增删改查-service和impl
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14352629.html
Copyright © 2020-2023  润新知