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;
}

 

posted @ 2018-04-01 09:33  Echo宝贝儿  阅读(144)  评论(0编辑  收藏  举报