zoukankan      html  css  js  c++  java
  • jsc2019_qualE Card Collector

    题目大意

    给你n个点的坐标和权值

    问先在每一行选一个点再在每一列选一个没选过的点

    求最大权值和

    分析

    可以想到将点转化为边,将两个坐标对应两个点

    所以问题转化为选H+W个边

    使得所有边的度都不为0

    则最终这个图就会变为若干联通块

    每个个联通块正好有一个环

    我们将边权从大到小排序

    然后并查集维护一下联通块信息和是否正好包含一个环即可

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define int long long
    struct node {
        int x,y,w;
    };
    node d[200100];
    int n,m,H,W,fa[200100],is[200100];
    long long Ans;
    inline int sf(int x){return fa[x]==x?x:fa[x]=sf(fa[x]);}
    inline bool cmp(const node a,const node b){return a.w>b.w;}
    signed main(){
        int i,j,k;
        scanf("%lld%lld%lld",&m,&H,&W);
        n=H+W;
        for(i=1;i<=n;i++)fa[i]=i;
        for(i=1;i<=m;i++){
          scanf("%lld%lld%lld",&d[i].x,&d[i].y,&d[i].w);
          d[i].y+=H;
        }
        sort(d+1,d+m+1,cmp);
        for(i=1;i<=m;i++){
          int x=d[i].x,y=d[i].y;
          if(sf(x)!=sf(y)){
              if(is[sf(x)]&&is[sf(y)])continue;
              is[sf(y)]|=is[sf(x)];
              fa[sf(x)]=sf(y);
              Ans+=d[i].w;
          }else {
              if(!is[sf(x)]){
                is[sf(x)]=1;
                Ans+=d[i].w;
              }
          }
        }
        printf("%lld
    ",Ans);
        return 0;
    }
  • 相关阅读:
    关于“jdk”版本不支持问题的总结
    Linux系统下jdk卸载安装、配置
    weblogic-jdk 问题
    MCU有哪些复位因素
    MCU固件升级(OTA)的几种Flash划分方式
    003_Linux常用命令之文件操作
    002_Linux常用命令之目录操作
    001_Linux常用命令之ls命令
    dup与dup2函数
    Linux 系统查询机器最近重启时间命令
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/11414117.html
Copyright © 2011-2022 走看看