zoukankan      html  css  js  c++  java
  • 【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 }
  • 相关阅读:
    [Kali_Debian] 清除无用的库文件(清理系统,洁癖专用)-布布扣-bubuko.com
    给 Linux 系统“减肥”,系统垃圾清理_系统安装与配置管理_Linux Today
    命令行选项
    SQL 优化
    精通initramfs构建step by step
    常用正则表达式
    Chrome_浏览器开发人员工具
    按键精灵
    CMD命令大全
    50种折纸方法
  • 原文地址:https://www.cnblogs.com/Troywar/p/7735015.html
Copyright © 2011-2022 走看看