【BZOJ 2744】【HEOI2012】朋友圈

题目链接:

     TP

题解:

  对于A国,我们发现,最大团一定不大于2。对于B国,发现同奇偶性点之间都有边,不同奇偶性之间可能有边,也就是说对于B国是一个二分图最大团,也就是求B国补图的二分图最大独立集。然后,我们枚举使用A国的人员,将其与B国连接的点做一个补图,跑跑匈牙利即可。

  【注】大视野上测试点和题面不一样啊!MMP没有t读入,只有一组数据,日哦!!

代码:

  

  1 #include <cstdio>
  2 #include <iostream>
  3 #include <cstring>
  4 
  5 using namespace std;
  6 
  7 inline int read(){
  8     int s=0,k=1;char ch=getchar();
  9     while(ch<'0'|ch>'9')    ch=='-'?k=-1:0,ch=getchar();
 10     while(ch>47&ch<='9')    s=s*10+(ch^48),ch=getchar();
 11     return s*k;
 12 }
 13 
 14 const int N=3e3+3;
 15 
 16 int A,B,M;
 17 
 18 struct edges{
 19     int v;edges *last;
 20 }edge[N*N],*head[N<<2];int cnt;
 21 
 22 inline void push(int u,int v){
 23     edge[++cnt]=(edges){v,head[u]};head[u]=edge+cnt;
 24 }
 25 
 26 struct Country{
 27     int sgl[N<<2],cpl[N<<2];
 28     int cnt_sgl,cnt_cpl;
 29     int val[N<<2],re[N<<2];
 30     inline void add(int x,int pos){
 31         if(x&1){
 32             sgl[++cnt_sgl]=pos;
 33             val[pos]=x;re[pos]=cnt_sgl;
 34         }else{
 35             cpl[++cnt_cpl]=pos;
 36             val[pos]=x;re[pos]=cnt_cpl;
 37         }
 38     }
 39     inline void clear(){
 40         cnt_sgl=cnt_cpl=0;
 41     }
 42 }a,b;
 43 
 44 int f[N<<2];bool vis[N<<2];
 45 
 46 inline bool find(int x){
 47 
 48     for(edges *i=head[x];i;i=i->last){
 49         if(!vis[i->v]){
 50             vis[i->v]=true;
 51             if(f[i->v]==-1||find(f[i->v])){
 52                 f[i->v]=x;
 53                 return true;
 54             }
 55         }
 56     }
 57     return false;
 58 }
 59 
 60 int v[500][N<<2],size[N<<2],tt[N<<2];
 61 
 62 inline void build(){
 63     for(int i=1;i<=b.cnt_sgl;i++)
 64         if(tt[b.sgl[i]]==2){
 65         for(int j=1;j<=b.cnt_cpl;j++)
 66             if(tt[b.cpl[j]]==2){
 67                 int x=b.val[b.sgl[i]]|b.val[b.cpl[j]];
 68                 int t(0);
 69                 while(x) t+=x&1,x>>=1;
 70                 if((~t)&1)
 71                     push(i,j);
 72             }
 73         }
 74 }
 75 
 76 inline int solve(){
 77     memset(f,-1,sizeof(f));
 78     int ret=0;
 79     for(int i=1;i<=B;i++)
 80         ret+=tt[i]==2;
 81     for(int i=1;i<=b.cnt_sgl;i++){
 82         if(tt[b.sgl[i]]==2){
 83         memset(vis,0,sizeof(vis));
 84             if(find(i))
 85                 ret--;
 86         }
 87     }
 88     return ret;
 89 }
 90 
 91 inline void clear(){
 92     memset(head,0,sizeof(head));
 93     cnt=0;
 94 }
 95 
 96 
 97 int main(){
 98     // freopen(".in","r",stdin);
 99     // freopen(".out","w",stdout);
100         clear();
101         a.clear();b.clear();
102         memset(v,0,sizeof(v));
103         memset(size,0,sizeof(size));
104         A=read(),B=read(),M=read();
105         for(int i=1;i<=A;i++)    a.add(read(),i);
106         for(int i=1;i<=B;i++)    b.add(read(),i);
107         for(int i=1,u,vv;i<=M;i++){
108             u=read(),vv=read();
109             v[u][++size[u]]=vv;
110         }
111         for(int i=1;i<=B;i++)
112             tt[i]=2;        
113         build();
114         int ans=(a.cnt_sgl>0)+(a.cnt_cpl>0);
115         ans=max(ans,solve());
116         memset(tt,0,sizeof(tt));
117         for(int i=1;i<=a.cnt_sgl;i++){
118             for(int j=1;j<=size[a.sgl[i]];j++)
119                 tt[v[a.sgl[i]][j]]=2;
120             clear();
121             build();
122             ans=max(ans,solve()+1);
123             for(int j=1;j<=size[a.sgl[i]];j++)
124                 tt[v[a.sgl[i]][j]]=0;
125         }
126         for(int j=1;j<=a.cnt_cpl;j++){
127             for(int k=1;k<=size[a.cpl[j]];k++)
128                 tt[v[a.cpl[j]][k]]=2;
129             clear();
130             build();
131             ans=max(ans,solve()+1);
132             for(int k=1;k<=size[a.cpl[j]];k++)
133                 tt[v[a.cpl[j]][k]]=0;
134         }
135         for(int i=1;i<=a.cnt_sgl;i++){
136             for(int j=1;j<=size[a.sgl[i]];j++)
137                 tt[v[a.sgl[i]][j]]++;
138             for(int j=1;j<=a.cnt_cpl;j++){
139                 for(int k=1;k<=size[a.cpl[j]];k++)
140                     tt[v[a.cpl[j]][k]]++;
141                 clear();
142                 build();
143                 ans=max(ans,solve()+2);
144                 for(int k=1;k<=size[a.cpl[j]];k++)
145                     tt[v[a.cpl[j]][k]]--;
146             }
147             for(int j=1;j<=size[a.sgl[i]];j++)
148                 tt[v[a.sgl[i]][j]]--;
149         }
150         printf("%d
",ans);
151     
152 }
原文地址:https://www.cnblogs.com/Troywar/p/7735015.html