因为$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 }