zoukankan      html  css  js  c++  java
  • 解题:HEOI 2012 朋友圈

    题面

    因为$A$中只有奇偶性不同的人才能做朋友,所以A中只可能出0/1/2个人,分类讨论

    然后$B$中求最大团,转成补图后正好是个二分图(不然就不用做了),求最大点独立集=总点数-最大匹配

    我洛谷上交的时候建边的时候制杖了,成了$O(n^2m^2)$建边,还好数据水跑不满+网络流跑得快900ms救回来了,估计BZOJ肯定gg了,正确的做法是直接对B全部建然后走边的时候判一下

      1 #include<cstdio>
      2 #include<vector>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 const int N=100005,M=4000005,inf=1e9;
      7 int p[N],from[M],noww[M],goal[M],flw[M],flow[M];
      8 int a[N],b[N],pp[N],ch[N],dep[N],que[N];
      9 int T,n,m,s,t,fr,bk,q,t1,t2,cnt,ans;
     10 vector<int> ve[N];
     11 vector<int> ::iterator it; 
     12 bool Odd(int x){return x&1;}
     13 bool Even(int x){return !(x&1);}
     14 int Bitcount(int x)
     15 {
     16     int ret=0;
     17     while(x)
     18         ret++,x-=x&-x;
     19     return ret;
     20 }
     21 void Link(int f,int t,int v)
     22 {
     23     noww[++cnt]=p[f],p[f]=cnt,from[cnt]=f;
     24     goal[cnt]=t,flw[cnt]=flow[cnt]=v;
     25     noww[++cnt]=p[t],p[t]=cnt,from[cnt]=t;
     26     goal[cnt]=f,flw[cnt]=flow[cnt]=0;
     27 }
     28 bool Layering(int st,int ed)
     29 {
     30     for(int i=1;i<=ed;i++) 
     31         pp[i]=p[i],dep[i]=-1;
     32     dep[st]=0,que[fr=bk=0]=st;
     33     while(fr<=bk)
     34     {
     35         int tn=que[fr++];
     36         for(int i=pp[tn];i;i=noww[i])
     37             if(ch[from[i]]&&ch[goal[i]])
     38                 if(dep[goal[i]]==-1&&flow[i])
     39                     dep[goal[i]]=dep[tn]+1,que[++bk]=goal[i];
     40     }
     41     return ~dep[ed];
     42 }
     43 int Augmenting(int nd,int ed,int mn)
     44 {
     45     if(nd==ed||!mn) return mn;
     46     int tmp=0,tep=0;
     47     for(int i=pp[nd];i;i=noww[i])
     48         if(ch[from[i]]&&ch[goal[i]])
     49         {
     50             pp[nd]=i;
     51             if(dep[goal[i]]==dep[nd]+1)
     52                 if(tep=Augmenting(goal[i],ed,min(mn,flow[i])))
     53                 {
     54                     flow[i]-=tep,mn-=tep;
     55                     flow[i^1]+=tep,tmp+=tep;
     56                     if(!mn) break;
     57                 }
     58         }
     59     return tmp;
     60 }
     61 int Dinic_Maxflow(int st,int ed)
     62 {
     63     int ret=0;
     64     while(Layering(st,ed))
     65         ret+=Augmenting(st,ed,inf);
     66     return ret;
     67 }
     68 int main()
     69 {
     70     register int i,j,k;
     71     scanf("%d",&T);
     72     while(T--)
     73     {
     74         scanf("%d%d%d",&n,&m,&q),ans=0;
     75         for(i=1;i<=n;i++) ve[i].clear();
     76         for(i=1;i<=n;i++) scanf("%d",&a[i]);
     77         for(i=1;i<=m;i++) scanf("%d",&b[i]);
     78         for(i=1;i<=q;i++) 
     79             scanf("%d%d",&t1,&t2),ve[t1].push_back(t2);
     80         cnt=1,s=m+1,t=s+1;
     81         for(i=1;i<=m+2;i++) ch[i]=1,p[i]=0;
     82         for(i=1;i<=m;i++)
     83             for(j=i+1;j<=m;j++)
     84                 if(Odd(b[i]^b[j])&&Even(Bitcount(b[i]|b[j])))
     85                     Odd(b[i])?Link(i,j,1):Link(j,i,1);
     86         for(i=1;i<=m;i++) 
     87             Odd(b[i])?Link(s,i,1):Link(i,t,1);
     88         ans=max(ans,m-Dinic_Maxflow(s,t));
     89         for(i=1;i<=n;i++)
     90         {
     91             int tmp=0;
     92             for(j=1;j<=m;j++) ch[j]=0;
     93             for(j=2;j<=cnt;j++) flow[j]=flw[j];
     94             for(it=ve[i].begin();it!=ve[i].end();it++) tmp++,ch[*it]=1;
     95             ans=max(ans,tmp-Dinic_Maxflow(s,t)+1);
     96         }
     97         for(i=1;i<=n;i++)
     98             for(k=i+1;k<=n;k++)
     99                 if(Odd(a[i]^a[k]))
    100                 {
    101                     int tmp=0;
    102                     for(j=1;j<=m;j++) ch[j]=0;
    103                     for(j=2;j<=cnt;j++) flow[j]=flw[j];
    104                     for(it=ve[i].begin();it!=ve[i].end();it++) ch[*it]++;
    105                     for(it=ve[k].begin();it!=ve[k].end();it++) ch[*it]++;
    106                     for(j=1;j<=m;j++) ch[j]==2?tmp++,ch[j]=1:ch[j]=0;
    107                     ans=max(ans,tmp-Dinic_Maxflow(s,t)+2);
    108                 }
    109         printf("%d
    ",ans);
    110     }
    111     return 0;
    112 }
    View Code
  • 相关阅读:
    Ubuntu下安装Packet Tracer5.3过程
    杭电OJ-2093_考试排名
    杭电OJ-2072_单词数
    杭电OJ-2054_A == B ?
    杭电OJ-2032_杨辉三角
    c++不跳过空白符输入一行字符串
    【Little_things】调戏人小玩意_按钮位置移动文字改变(C#)
    笔记本以太网卡共享的无线网卡的网络
    杭电OJ-2104_hide handkerchief超简洁代码
    2019杭电多校一 C. Milk (dp)
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10284006.html
Copyright © 2011-2022 走看看