zoukankan      html  css  js  c++  java
  • CF875F Royal Questions[最大生成基环树森林]

    这题这场比赛一堆人秒切。。果然还是我太菜了吗


    题意:二分图,右边$m$个点每个点$i$向左边有且仅有两条连边,边权都是$a_i$。求最大匹配。

    一个朴素思想,二分图匹配,用贪心带匈牙利搞一搞,但是复杂度$O(mn)$。`````

    注意字眼“只能选一次”。对于同一个点连出的两条边只能择一。也就是说,左边由若干个点对,每选其一有一个代价。那么,不妨将这个点对连边,$x o y$,则表示$y$被选了。这样,每个点最多只能被选一次,入度至多为1,也就是说是一个最大的基环树和树的森林,然后套板子就好了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #define dbg(x) cerr << #x << " = " << x <<endl
     8 #define dbg2(x,y) cerr<< #x <<" = "<< x <<"  "<< #y <<" = "<< y <<endl
     9 using namespace std;
    10 typedef long long ll;
    11 typedef double db;
    12 typedef pair<int,int> pii;
    13 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
    14 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
    15 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
    16 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
    17 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
    18 template<typename T>inline T read(T&x){
    19     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    20     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
    21 }
    22 const int N=2e5+7;
    23 struct thxorz{
    24     int u,v,w;
    25     inline bool operator <(const thxorz&A)const{return w<A.w;}
    26 }e[N];
    27 int cir[N],anc[N];
    28 int n,m,ans;
    29 inline int get_anc(int x){return anc[x]==x?x:anc[x]=get_anc(anc[x]);}
    30 
    31 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
    32     read(n),read(m);
    33     for(register int i=1;i<=m;++i)read(e[i].u),read(e[i].v),read(e[i].w);
    34     for(register int i=1;i<=n;++i)anc[i]=i;
    35     sort(e+1,e+m+1);
    36     for(register int i=m;i;--i){
    37         int fu=get_anc(e[i].u),fv=get_anc(e[i].v);
    38         if(fu==fv){
    39             if(!cir[fu])cir[fu]=1,ans+=e[i].w;
    40         }
    41         else{
    42             if(!cir[fu]||!cir[fv])cir[fv]=cir[fu]|cir[fv],anc[fu]=fv,ans+=e[i].w;
    43         }
    44     }
    45     return printf("%d
    ",ans),0;
    46 }
    View Code

    总结:简化问题能力不够啊。如果看出是单纯的左边点对二择、无视右边的话,是很容易想出来的。这种简单问题都是可以尝试转化的。

  • 相关阅读:
    H5页面获取屏幕宽高
    装修注意事项
    两列等高布局
    html/css
    css的几种垂直水平居中方法
    3分钟看懂flex布局
    Android手机里H5页面滚动图片时出现白屏
    JavaScript正则表达式——函数
    javascript正则表达式——语法
    【react】子组件向父组件传值
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/11683487.html
Copyright © 2011-2022 走看看