cogs 2620. [HEOI2012]朋友圈
/*70分 被卡T*/ #include<iostream> #include<cstdio> #include<cstring> using namespace std; int a[210],b[3010],na,nb,m,head[3010],num; int T1,T2,ban[3010],Link[3010],vis[3010],tim[3010],T; bool map[210][3010]; struct node{int to,pre;}e[1000010]; void Insert(int from,int to){ e[++num].to=to; e[num].pre=head[from]; head[from]=num; } int count(int x){ int res=0; while(x){ res+=x&1; x>>=1; } return res; } bool find(int x){ if(ban[x]==T1)return 0; for(int i=head[x];i;i=e[i].pre){ int to=e[i].to; if((ban[to]!=T1)&&(vis[to]!=T2)){ vis[to]=T2; if(tim[to]!=T1||!Link[to]||find(Link[to])){ tim[to]=T1; Link[to]=x; return 1; } } } return 0; } int mis(int x=0,int y=0){ T1++;int res=0; for(int i=1;i<=nb;i++) if(map[x][i]||map[y][i])ban[i]=T1,res++; for(int i=1;i<=nb;i++) if(b[i]&1){ T2++; if(find(i))res++; } return nb-res; } int main(){ freopen("friends.in","r",stdin);freopen("friends.out","w",stdout); scanf("%d",&T); while(T--){ memset(map,1,sizeof(map)); memset(head,0,sizeof(head)); memset(Link,0,sizeof(Link)); memset(ban,0,sizeof(ban)); memset(tim,0,sizeof(tim)); memset(vis,0,sizeof(vis)); num=0;T1=0;T2=0; scanf("%d%d%d",&na,&nb,&m); for(int i=1;i<=na;i++)scanf("%d",&a[i]); for(int i=1;i<=nb;i++)scanf("%d",&b[i]); int x,y; for(int i=1;i<=m;i++){ scanf("%d%d",&x,&y); map[x][y]=0; } for(int i=1;i<=nb;i++) for(int j=i;j<=nb;j++){ if(((b[i]^b[j])%2==1)&&(count(b[i]|b[j])%2==0)) Insert(i,j),Insert(j,i); } for(int i=1;i<=nb;i++)map[0][i]=0; int ans=mis(); for(int i=1;i<=na;i++)ans=max(ans,mis(i)+1); for(int i=1;i<=na;i++) for(int j=1;j<=na;j++) if((a[i]^a[j])%2==1)ans=max(ans,mis(i,j)+1); printf("%d\n",ans); } return 0; }