妙啊 我好菜啊
(冷静分析.jpg)
首先A国很显然同奇或同偶才是朋友 最大团肯定是2
然后 最大团=补图的最大独立集
对于B国,取个补图会好理解点。
奇数点之间没边 偶数点之间也没边(因为原来肯定有盆友关系)
当然 会因为第二个条件 有一些奇偶之间也没边
很显然的二分图>_<
那你就可以枚举A国选哪些(0,1,2个都行)
把B中有可能在团中的拿来跑一下最大匹配就好了
#include<bits/stdc++.h>
using namespace std;
const int N=202,M=3002;
inline int read(){
int x=0,f=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0' && ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();}
return x*f;
}
int fir[M],nex[M*M],go[M*M],len;
bool v[N][M];
void ins(int x,int y){
nex[++len]=fir[x],fir[x]=len,go[len]=y;
}
int T,ans,t[M],o[M],P[M],TT;
int n,m,a[N],b[M],c[2],cl;
int fw(int x){
for(int k=fir[x];k;k=nex[k]){
int y=go[k]; if(t[y]==TT || o[y]!=T)continue;
t[y]=TT;
if(!P[y] || fw(P[y])){P[y]=x; return 1;}
}
return 0;
}
void solve(){
++T; int i,j,s=cl;
if(!cl) { for(i=1;i<=m;++i) o[i]=T,P[i]=0; s=m; }
else
for(i=1;i<=m;++i){
for(j=0;j<cl;++j)if(!v[c[j]][i])break;
if(j==cl)o[i]=T,++s; P[i]=0;
}
for(i=1;i<=m;++i)
if(o[i]==T && b[i]&1){
++TT; s-=fw(i);
}
ans=max(ans,s);
}
void dfs(int x){
if(x>n || cl>1){solve(); return;}
dfs(x+1);
if(cl>0 && (a[c[0]]&1)^(a[x]&1) || !cl){
c[cl++]=x;
dfs(x+1);
cl--;
}
}
int main(){
n=read(),m=read(); int i,j,k=read();
for(i=1;i<=n;++i)a[i]=read();
for(i=1;i<=m;++i)b[i]=read();
for(i=1;i<=k;++i){
int x=read(),y=read();
v[x][y]=1;
}
for(i=1;i<=m;++i)
for(j=i+1;j<=m;++j) if((b[i]&1)^(b[j]&1)){
int u=b[i]|b[j],s=0;
while(u){
if(u&1)++s; u>>=1;
}
if(!(s&1))ins(i,j),ins(j,i);
}
ans=0; dfs(1);
printf("%d\n",ans);
return 0;
}