zoukankan      html  css  js  c++  java
  • 【BZOJ 2744】 2744: [HEOI2012]朋友圈 (最大团,二分图匹配,构图)

    2744: [HEOI2012]朋友圈

    Description

    在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着。一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他人的尊敬,所以现在就是需要你求朋友圈的最大数目。
    两个国家看成是AB两国,现在是两个国家的描述:
    1.         A国:每个人都有一个友善值,当两个A国人的友善值a、b,如果a xor b mod 2=1,
    那么这两个人都是朋友,否则不是;
    2.         B国:每个人都有一个友善值,当两个B国人的友善值a、b,如果a xor b mod 2=0
    或者 (a or b)化成二进制有奇数个1,那么两个人是朋友,否则不是朋友;
    3.         A、B两国之间的人也有可能是朋友,数据中将会给出A、B之间“朋友”的情况。
    4.     在AB两国,朋友圈的定义:一个朋友圈集合S,满足

    S∈A∪ B                  ,对于所有的i,j∈  S ,i 和       j   是朋友

    由于落后的古代,没有电脑这个也就成了每年最大的难题,而你能帮他们求出最大朋 友圈的人数吗?

    Input

    第一行t<=6,表示输入数据总数。
    接下来t个数据:
    第一行输入三个整数A,B,M,表示A国人数、B国人数、AB两国之间是朋友的对数;第二行A个数ai,表示A国第i个人的友善值;第三行B个数bi,表示B国第j个人的友善值;
    第4——3+M行,每行两个整数(i,j),表示第i个A国人和第j个B国人是朋友。

    Output

    输出t行,每行,输出一个整数,表示最大朋友圈的数目。

    Sample Input

    2 4 7
    1 2
    2 6 5 4
    1 1
    1 2
    1 3
    2 1
    2 2
    2 3
    2 4

    Sample Output

    5
    【样例说明】
    最大朋友圈包含A国第1、2人和B国第1、2、3人。

    HINT

    【数据范围】

    两类数据

    第一类:|A|<=200 |B| <= 200

    第二类:|A| <= 10 |B| <= 3000

    【分析】

      %%%大颓果:http://blog.csdn.net/u010336344/article/details/56287207

      普通的最大团貌似是NPC问题??

      所以这题一定有特殊性质?

      A国不奇偶的认识,明显最多只能选2个人。

      B过同奇同偶的认识,如果认识的连边,那么有两个完全图,又有or什么的也是朋友,所以两个团中间还有边。

      那么其实可以建反图求最大点独立集。

      A国的小朋友的影响就直接枚举就好了。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 using namespace std;
      7 #define Maxn 3010
      8 
      9 int mymax(int x,int y) {return x>y?x:y;}
     10 
     11 int a[Maxn],b[Maxn];
     12 
     13 struct node
     14 {
     15     int x,y,next;
     16 }t[Maxn*Maxn];
     17 int first[Maxn],len;
     18 
     19 void ins(int x,int y)
     20 {
     21     t[++len].x=x;t[len].y=y;
     22     t[len].next=first[x];first[x]=len;
     23 }
     24 
     25 int bx[Maxn],by[Maxn];
     26 bool vis[Maxn];
     27 bool eg[Maxn][Maxn];
     28 
     29 int chw[Maxn],match[Maxn];
     30 
     31 bool ffind(int x,int nt)
     32 {
     33     for(int i=first[x];i;i=t[i].next) if(chw[t[i].y]!=nt&&vis[t[i].y])
     34     {
     35         int y=t[i].y;
     36         chw[y]=nt;
     37         if(match[y]==0||ffind(match[y],nt))
     38         {
     39             match[y]=x;
     40             return 1;
     41         }
     42     }
     43     return 0;
     44 }
     45 
     46 int get_ans()
     47 {
     48     int ans=0,nt=0,h=0;
     49     for(int i=1;i<=bx[0]+by[0];i++) if(vis[i]) h++;
     50     memset(chw,0,sizeof(chw));
     51     memset(match,0,sizeof(match));
     52     for(int i=1;i<=bx[0];i++) if(vis[bx[i]])
     53     {
     54         nt++;
     55         if(ffind(bx[i],nt)) ans++;
     56     }
     57     return h-ans;
     58 }
     59 
     60 bool check(int x)
     61 {
     62     int nw=0;
     63     while(x)
     64     {
     65         if(x&1) nw++;
     66         x>>=1;
     67     }
     68     return nw&1;
     69 }
     70 
     71 int main()
     72 {
     73     int n,m,k;
     74     scanf("%d%d%d",&n,&m,&k);
     75     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
     76     for(int i=1;i<=m;i++) scanf("%d",&b[i]);
     77     bx[0]=by[0]=0;
     78     for(int i=1;i<=m;i++) if(b[i]&1) bx[++bx[0]]=i;
     79     for(int i=1;i<=m;i++) if(!(b[i]&1)) by[++by[0]]=i;
     80     for(int i=1;i<=bx[0];i++)
     81      for(int j=1;j<=by[0];j++)
     82      {
     83          if(!check(b[bx[i]]|b[by[j]]))  ins(bx[i],by[j]);
     84      }
     85     for(int i=1;i<=m;i++) vis[i]=1;
     86     int ans=get_ans();
     87     
     88     memset(eg,0,sizeof(eg));
     89     for(int i=1;i<=k;i++)
     90     {
     91         int x,y;
     92         scanf("%d%d",&x,&y);
     93         eg[x][y]=1;
     94     }
     95     
     96     for(int i=1;i<=n;i++)
     97     {
     98         for(int j=1;j<=m;j++) vis[j]=eg[i][j];
     99         ans=mymax(ans,get_ans()+1);
    100         for(int j=1;j<=m;j++) vis[j]=1;
    101     }
    102     for(int i=1;i<=n;i++)
    103     {
    104         for(int ii=i+1;ii<=n;ii++) if((a[i]&1)^(a[ii]&1))
    105         {
    106             for(int j=1;j<=m;j++) vis[j]=eg[ii][j]&eg[i][j];
    107             ans=mymax(ans,get_ans()+2);
    108             for(int j=1;j<=m;j++) vis[j]=1;
    109         }
    110     }
    111     printf("%d
    ",ans);
    112     return 0;
    113 }
    View Code

    数据弱??一个很明显的错一开始还是AC了。。

    2017-02-21 17:20:50

  • 相关阅读:
    MySQL 5.5版本数据库介绍与二进制安装
    nginx配置文件的基础优化
    yum源是什么
    微服务之间调用token管理
    微服务之间调用事务处理
    idea
    sentry
    infinispan配置
    微服务事务处理
    高并发处理
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6425110.html
Copyright © 2011-2022 走看看