• Card Collector AtCoder


    题意:

    给定一个H行W列的矩阵,在矩阵的格点上放带权值的卡片(一个点上能放多张)。

    现在从每行每列各拿走一张卡片(没有可以不拿),求可以拿到的最大权值。

    卡片数N<=1e5,H,W<=1e5

    思路:

    显然可以构造成一个最大费用流模型:每张卡片到它对应的行列各有一条费用0,容量1的边;源点到每张卡片有一条费用为卡片权值,容量1的边;每个行列到汇点有一条费用0,容量1的边。但是边数有5e5,应该会超时吧?

    观察这个图发现除去源点和汇点是一张二分图,想到是否可以利用二分图的性质简化问题。

    手动模拟一波发现好像只要贪心地从大到小拿,能拿则拿,那么就能得到最佳答案。如何检测是否还能拿呢?

    HALL定理:如果一个二分图上,左部|X|<=右部|Y|,如果左部点的任意一个子集U,U相连边对应右部的子集V都有|U|<=|V|,那么这个二分图有最大匹配|X|。

    每次拿走点相当于在U中增加点,在V中增加边,用并查集维护一下集合的大小即可。

    1. 所在行列在同个集合中,直接判断这个集合是否满足条件
    2. 所在行列不在同一个集合中,那么判断这两个集合合并后是否满足条件,若是则合并
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=2e5+5;
    struct node{
        int r,c,a;
        friend bool operator<(node a,node b){
            return a.a>b.a;
        }
    }st[maxn];
    int fa[maxn],S[maxn],T[maxn];
    int n,H,W;
    int init(){
        for(int i=1;i<=H+W;i++){
            fa[i]=i;
            T[i]=1;
        }
    }
    int find(int x){
        return x==fa[x]?x:fa[x]=find(fa[x]);
    }
    int main(){
        cin>>n>>H>>W;
        init();
        for(int i=1;i<=n;i++){
            scanf("%d%d%d",&st[i].r,&st[i].c,&st[i].a);
        }
        sort(st+1,st+1+n);
        ll ans=0;
        for(int i=1;i<=n;i++){
    //        printf("%d %d %d
    ",st[i].r,st[i].c,st[i].a);
            int fr=find(st[i].r),fc=find(H+st[i].c);
            if(fr==fc){//两个在同一集合内
                if(T[fc]>=S[fc]+1){
                    S[fc]++;
                    ans=ans+st[i].a;
                }
            }
            else{//两个不在同一集合内,要合并
                if(T[fr]+T[fc]>=S[fr]+S[fc]+1){
                    fa[fr]=fc;
                    T[fc]+=T[fr];
                    S[fc]=S[fr]+S[fc]+1;
                    ans=ans+st[i].a;
                }
            }
        }
        printf("%lld
    ",ans);
    }
    
  • 相关阅读:
    Remmina:一个 Linux 下功能丰富的远程桌面共享工具(转载)
    Linux安装多功能词典GoldenDict
    Ubuntu18.04 更改GRUB引导菜单背景图片和默认启动项
    ubuntu 18.04网卡命名规则改回传统的ethx
    Linux Putty 复制粘贴
    Ubuntu 18.04图形化软件包管理器
    Ubuntu 18.04 安装 Broadcom Limited BCM43142无线网卡驱动
    Linux下通过rdesktop连接Windows远程桌面
    Debian9.5 系统配置NFS配置说明
    CentOS6.9下NFS配置说明
  • 原文地址:https://www.cnblogs.com/ucprer/p/11800975.html
Copyright © 2020-2023  润新知