zoukankan      html  css  js  c++  java
  • 解题:WC 2007 石头剪刀布

    题面

    要我们把边定向,最大化留下来的三元环数目......并不能直接做,考虑容斥,去掉不合法的数目。

    那么三个点不成环当且仅当有一个点出度为2一个点入度为2,发现最终答案就是$C_n^3-sum C_{outdeg}^2$,然后因为下凸函数和费用流相似的性质可以拆边费用流:

    每个点向汇点连一坨流量为$1$费用为$0,1,2...$的边,然后再把每条边向连接的点连流量为$1$费用为$0$的边表示使得一个点出度加$1$,最后原点向每条边连流量为$1$费用为$0$的边

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=10005,M=100005,inf=1e9;
     7 int p[N],noww[2*M],goal[2*M],flow[2*M],cost[2*M];
     8 int mflw[N],mcst[N],pren[N],pree[N],queu[N],degr[N];
     9 int game[N][N],gamx[N],gamy[N],numb[N]; queue<int> qs;
    10 int n,m,s,t,t1,t2,t3,t4,id,rd,cnt,num,ans; 
    11 void link(int f,int t,int v,int c)
    12 {
    13     noww[++cnt]=p[f],p[f]=cnt;
    14     goal[cnt]=t,flow[cnt]=v,cost[cnt]=c;
    15     noww[++cnt]=p[t],p[t]=cnt;
    16     goal[cnt]=f,flow[cnt]=0,cost[cnt]=-c;
    17 }
    18 void Init(int st,int ed)
    19 {
    20     memset(mflw,0x3f,sizeof mflw);
    21     memset(mcst,0x3f,sizeof mcst);
    22     memset(queu,0,sizeof queu),pren[ed]=-1;
    23     qs.push(st),queu[st]=true,mcst[st]=0;
    24 }
    25 bool SP(int st,int ed)
    26 {
    27     Init(st,ed);    
    28     while(!qs.empty())
    29     {
    30         int tn=qs.front(); 
    31         qs.pop(),queu[tn]=false;
    32         for(int i=p[tn],g;i;i=noww[i])
    33             if(mcst[g=goal[i]]>mcst[tn]+cost[i]&&flow[i])
    34             {
    35                 pree[g]=i,pren[g]=tn;
    36                 mcst[g]=mcst[tn]+cost[i];
    37                 mflw[g]=min(mflw[tn],flow[i]);
    38                 if(!queu[g]) qs.push(g),queu[g]=true;
    39             }
    40     }
    41     return ~pren[ed];
    42 }
    43 void MCMF(int st,int ed)
    44 {
    45     while(SP(st,ed))
    46     {
    47         ans+=mflw[ed]*mcst[ed],id=ed;
    48         while(id!=st)
    49         {
    50             flow[pree[id]]-=mflw[ed];
    51             flow[pree[id]^1]+=mflw[ed];
    52             id=pren[id];
    53         }
    54     }
    55 }
    56 int main()
    57 {
    58     scanf("%d",&n),cnt=1,s=n+1,num=t=n+2;
    59     for(int i=1;i<=n;i++)
    60         for(int j=1;j<=n;j++)
    61         {
    62             scanf("%d",&game[i][j]);
    63             if(game[i][j]==2)
    64             {
    65                 if(i<=j) 
    66                 {
    67                     num++,gamx[num]=i,gamy[num]=j;
    68                     link(num,i,1,0),link(num,j,1,0);
    69                     numb[i]++,numb[j]++,link(s,num,1,0);
    70                 }
    71             }
    72             else degr[i]+=game[i][j];
    73         } 
    74     for(int i=1;i<=n;i++)
    75     {
    76         ans+=degr[i]*degr[i];
    77         for(int j=1;j<=numb[i];j++)
    78             link(i,t,1,2*(degr[i]+j)-1);
    79     }
    80     MCMF(s,t);
    81     printf("%d
    ",n*(n-1)*(n-2)/6-(ans-n*(n-1)/2)/2);
    82     for(int i=t+1;i<=num;i++)
    83     {
    84         int oppo,numx=gamx[i],numy=gamy[i];
    85         for(int j=p[i];j;j=noww[j])
    86             if(goal[j]!=s&&!flow[j]) 
    87                 {oppo=goal[j]; break;}
    88         game[numx][numy]=oppo==numx;
    89         game[numy][numx]=game[numx][numy]^1;
    90     }
    91     for(int i=1;i<=n;i++,puts(""))
    92         for(int j=1;j<=n;j++)
    93             printf("%d ",game[i][j]);
    94     return 0;
    95 }
    View Code
  • 相关阅读:
    hdu 4948 Kingdom(推论)
    codeforces 407 div1 A题(Functions again)
    Atcoder regular Contest 073(C
    Atcoder regular Contest 073(D
    Nginx阅读笔记(二)之location的用法
    Nginx阅读笔记
    django virtualenv
    Supervisor
    捕捉攻击者
    django user模块改写
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10181586.html
Copyright © 2011-2022 走看看