bzoj 2744 朋友圈
题目大意:
两个国家 各有A和B个人,每个人有一个数值。
若两个A国的人满足$val_i\space xor \space val_j \mod 2 =1$ 则他们为朋友
若两个B国的人满足$val_i\space xor \space val_j \mod 2 =0$或者二进制下$val_i \space or\space val_j$中有奇数个1 则他们为朋友
给出一些A国的人与B国的人的朋友关系
求图的最大团
思路:
直接求最大团并不好求,发现A国的人最多取2个
而B国形成的图的反图一定为二分图(奇偶相连),而二分图反图的最大团=最大点独立集=$n-$最大匹配
因此我们先建出B国的反图,枚举选A国的人的情况,对每种情况在图上打$tag$ 跑$Dinic$即可
(完全忘记匈牙利.jpg
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #include<set> 11 #define ll long long 12 #define db double 13 #define inf 2139062143 14 #define MAXN 3010 15 #define MAXM 5001000 16 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i) 17 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i) 18 #define ren for(register int i=fst[x];i;i=nxt[i]) 19 #define pb(i,x) vec[i].push_back(x) 20 #define pls(a,b) (a+b)%MOD 21 #define mns(a,b) (a-b+MOD)%MOD 22 #define mul(a,b) (1LL*(a)*(b))%MOD 23 using namespace std; 24 inline int read() 25 { 26 int x=0,f=1;char ch=getchar(); 27 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 28 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 29 return x*f; 30 } 31 int na,nb,m,ans,S,T,a[210],b[MAXN],t1,t2;vector<int> vec[210]; 32 struct Dinic 33 { 34 int S,T,fst[MAXN],nxt[MAXM<<1],to[MAXM<<1],val[MAXM<<1],cnt,cur[MAXN]; 35 int vis[MAXN],dis[MAXN],tot,q[MAXN],l,r,o1[MAXN],o2[MAXN]; 36 Dinic(){memset(fst,0,sizeof(fst));cnt=1;} 37 void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;} 38 void ins(int u,int v,int w) {add(u,v,w);add(v,u,0);} 39 int bfs() 40 { 41 q[l=r=1]=T,vis[T]=++tot,dis[T]=0;int x; 42 while(l<=r) 43 { 44 x=q[l++];ren if(o1[to[i]]==t1&&o2[to[i]]==t2&&vis[to[i]]!=tot&&val[i^1]) 45 dis[to[i]]=dis[x]+1,vis[to[i]]=tot,q[++r]=to[i]; 46 } 47 return vis[S]==tot; 48 } 49 int dfs(int x,int a) 50 { 51 if(x==T||!a) return a;int flw=0,f; 52 for(int& i=cur[x];i&&a;i=nxt[i]) 53 if(dis[to[i]]==dis[x]-1&&val[i]&&(f=dfs(to[i],min(a,val[i])))) 54 a-=f,flw+=f,val[i]-=f,val[i^1]+=f; 55 return flw; 56 } 57 int solve(int _s,int _t,int res=0) 58 { 59 S=_s,T=_t;int f;while(bfs()) 60 {rep(i,1,max(S,T)) cur[i]=fst[i];while(f=dfs(S,inf)) res+=f;} 61 return res; 62 } 63 }D; 64 int lowbit(int x) {return x&(-x);} 65 int cheq(int x,int res=0) {for(;x;x-=lowbit(x)) res++;return !(res&1);} 66 int vis[MAXN],vis2[MAXN]; 67 int main() 68 { 69 na=read(),nb=read(),m=read();int x,y,sum;S=nb+1,T=S+1; 70 rep(i,1,na) a[i]=read();rep(i,1,nb) b[i]=read(); 71 while(m--) x=read(),y=read(),pb(x,y); 72 rep(i,1,nb) if(b[i]&1) D.ins(S,i,1); 73 else {D.ins(i,T,1);rep(j,1,nb) if((b[j]&1)&&cheq(b[i]|b[j])) D.ins(j,i,1);} 74 rep(i,1,na) pb(i,S),pb(i,T); 75 ans=max(ans,nb-D.solve(S,T));D.solve(T,S); 76 rep(i,1,na) 77 { 78 sum=-2;rep(x,0,vec[i].size()-1) D.o1[vec[i][x]]=i,sum++; 79 t1=i,ans=max(ans,sum+1-D.solve(S,T));D.solve(T,S); 80 } 81 rep(i,1,na) if(a[i]&1) 82 { 83 rep(x,0,vec[i].size()-1) D.o1[vec[i][x]]=i+na;t1=i+na,sum=-2; 84 rep(j,i+1,na) if(!(a[j]&1)) 85 { 86 rep(x,0,vec[j].size()-1) D.o2[vec[j][x]]=i*na+j,sum+=(D.o1[vec[j][x]]==t1); 87 t2=i*na+j;ans=max(ans,sum+2-D.solve(S,T));D.solve(T,S);sum=-2; 88 } 89 } 90 printf("%d",ans); 91 }