zoukankan      html  css  js  c++  java
  • 51nod 1397 最大二分图(图论+思维)

    分析:其实是个数学题。。首先将已经匹配的m对连好,然后在不增加增广路的基础上尽量多地加边。对于二分图,增广路就是某条路径,第1、3、5、...、条边没有被连,第2、4、6...条边被连,且最后一条是被连的。然后将点分为4类:左边没有被匹配的为d1,左边与右边没有被匹配的点之间有通路的点为a1,左边与左边没有被匹配的点之间有通路的点为b1,左边没有与没有被匹配的点之间有通路的为c1,右边的同理设为a2、b2、c2、d2(- - 有点绕。。画个图就好理解了。。)。然后很容易可以得出结论:d1=n-m1,d2=n-m2,c1=c2,b1=a2,b2=a1,设a=a1,b=b1,c=c1,则a+b+c=m,并且由分类的定义和贪心可得,最终答案为ans=a^2+b^2+c^2+a*(n2-m)+b*(n1-m)+a*b。每个点至少连d条边,即c=0或c>=d,a>=d,b>=d,然后代到ans中讨论,又ans的单调性得到只有三种情况下可能取得最值,即(a,b,c)=(d,d,m-2*d),(m-2*d,d,d),(m-d,d,0),然后比较下谁大,注意检查无解情况即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<vector>
     5 using namespace std;
     6 typedef long long ll;
     7 ll n1,n2,m,d;
     8 ll f(ll a,ll b,ll c){return a*a+b*b+c*c+a*(n2-m)+b*(n1-m)+a*b;}
     9 int main(){
    10 //    freopen("e:\in.txt","r",stdin);
    11     int T;
    12     scanf("%d",&T);
    13     while(T--){
    14         ll ans;
    15         int k1=2,k2=2;
    16         scanf("%lld%lld%lld%lld",&n1,&n2,&m,&d);
    17         ll a1[3]={0,n1/2,m},a2[3]={0,n2/2,m};
    18         if(n1==m||n2==m){
    19             printf("%lld
    ",n1*n2);continue;
    20         }
    21         if(m>n1||m>n2||m-d<d){
    22             printf("-1
    ");continue;
    23         }
    24         if(n1>n2){ll t=n1;n1=n2;n2=t;}
    25         ans=f(m-d,d,0);
    26         if(m-2*d>=0){
    27             ans=max(ans,f(d,d,m-2*d));
    28             ans=max(ans,f(m-2*d,d,d));
    29         }
    30         printf("%lld
    ",ans);
    31     }
    32     return 0;
    33 }
  • 相关阅读:
    最佳买卖股票时期含冷冻期
    牛客网刷题笔记
    交换字符中的元素
    刷题总结
    牛客基础网刷题笔记
    买卖股票的最佳时机 II
    Solution -「51nod 1355」斐波那契的最小公倍数
    Solution -「51nod 1584」加权约数和
    Solution -「CF 1375G」Tree Modification
    Solution -「洛谷 P5787」「模板」二分图(线段树分治)
  • 原文地址:https://www.cnblogs.com/7391-KID/p/7587672.html
Copyright © 2011-2022 走看看