BZOJ 2744: [HEOI2012]朋友圈

妙啊 我好菜啊

(冷靜分析.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;
}
發佈了173 篇原創文章 · 獲贊 203 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章