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 }
View Code

 

posted @ 2019-03-18 10:49  jack_yyc  阅读(151)  评论(0编辑  收藏  举报