BZOJ 2744: [HEOI2012]朋友圈

本文探讨了一个社交网络中的朋友团问题,通过构建二分图并使用最大匹配算法来解决。针对两个国家的不同社交规则,文章详细介绍了如何进行问题转化、补图操作及最终实现最大团的计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

妙啊 我好菜啊

(冷静分析.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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值