hdu 2768 Cat vs. Dog 最大独立集 巧妙的建图

  题目分析:

    一个人要不是爱狗讨厌猫的人,要不就是爱猫讨厌狗的人。一个人喜欢的动物如果离开,那么他也将离开。问最多留下多少人。

  思路:

    爱猫和爱狗的人是两个独立的集合。若两个人喜欢和讨厌的动物是一样的,那么就建一条边。留下多少人,就是求最大独立集。

    最大独立集= 顶点数 - 最大匹配数

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<queue>
  6 using namespace std;
  7 const int N=505,INF=0x3f3f3f3f;
  8 int bmap[N][N],cx[N],cy[N],dx[N],dy[N];
  9 bool bmask[N];
 10 int nx,ny,dis,ans;
 11 bool searchpath()
 12 {
 13     queue<int> q;
 14     dis=INF;
 15     memset(dx,-1,sizeof(dx));
 16     memset(dy,-1,sizeof(dy));
 17     for(int i=1;i<=nx;i++)
 18     {
 19         if(cx[i]==-1){ q.push(i); dx[i]=0; }
 20         while(!q.empty())
 21         {
 22             int u=q.front(); q.pop();
 23             if(dx[u]>dis) break;
 24             for(int v=1;v<=ny;v++)
 25             {
 26                 if(bmap[u][v]&&dy[v]==-1)
 27                 {
 28                     dy[v]= dx[u] + 1;
 29                     if(cy[v]==-1) dis=dy[v];
 30                     else
 31                     {
 32                         dx[cy[v]]= dy[v]+1;
 33                         q.push(cy[v]);
 34                     }
 35                 }
 36             }
 37         }
 38     }
 39     return dis!=INF;
 40 }
 41 int findpath(int u)
 42 {
 43     for(int v=1;v<=ny;v++)
 44     {
 45         if(!bmask[v]&&bmap[u][v]&&dy[v]==dx[u]+1)
 46         {
 47             bmask[v]=1;
 48             if(cy[v]!=-1&&dy[v]==dis) continue;
 49             if(cy[v]==-1||findpath(cy[v]))
 50             {
 51                 cy[v]=u; cx[u]=v;
 52                 return 1;
 53             }
 54         }
 55     }
 56     return 0;
 57 }
 58 void maxmatch()
 59 {
 60     ans=0;
 61     memset(cx,-1,sizeof(cx));
 62     memset(cy,-1,sizeof(cy));
 63     while(searchpath())
 64     {
 65         memset(bmask,0,sizeof(bmask));
 66         for(int i=1;i<=nx;i++)
 67             if(cx[i]==-1) ans+=findpath(i);
 68     }
 69 }
 70 void init()
 71 {
 72     memset(bmap,0,sizeof(bmap));
 73 }
 74 struct node
 75 {
 76     int x,y;
 77 }c[N],d[N];
 78 int main()
 79 {
 80     //freopen("test.txt","r",stdin);
 81     int cas,i,j,k,n,a,b;
 82     char ch;
 83     scanf("%d",&cas);
 84     while(cas--)
 85     {
 86         scanf("%d%d%d",&a,&b,&n);
 87         init();
 88         j=k=0;
 89         for(i=1;i<=n;i++)
 90         {
 91             getchar();
 92             ch=getchar();
 93             if(ch==‘C‘) {
 94                 scanf("%d",&a);
 95                 c[j].x=a;
 96             }
 97             if(ch==‘D‘) {
 98                 scanf("%d",&a);
 99                 d[k].y=a;
100             }
101             scanf(" %c",&ch);
102             if(ch==‘C‘) {
103                 scanf("%d",&a);
104                 d[k++].x=a;
105             }
106             if(ch==‘D‘) {
107                 scanf("%d",&a);
108                 c[j++].y=a;
109             }
110         }
111         nx=j;ny=k;
112         for(i=0;i<nx;i++){
113             for(j=0;j<ny;j++){
114                 if(c[i].x==d[j].x||c[i].y==d[j].y)
115                     bmap[i+1][j+1]=1;
116             }
117         }
118         maxmatch();
119         printf("%d\n",n-ans);
120     }
121     return 0;
122 }

时间: 2024-10-09 11:24:01

hdu 2768 Cat vs. Dog 最大独立集 巧妙的建图的相关文章

hdu 2768 Cat vs. Dog (二分匹配)

Cat vs. Dog Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1422    Accepted Submission(s): 534 Problem Description The latest reality show has hit the TV: ``Cat vs. Dog''. In this show, a bunch

HDU——2768 Cat vs. Dog

Cat vs. Dog Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2279    Accepted Submission(s): 886 Problem Description The latest reality show has hit the TV: ``Cat vs. Dog''. In this show, a bunc

hdu 5093 Battle ships 匈牙利 很巧妙的建图思路

//这题逼我把匈牙利学了 之前一直很勤快敲网络流 而且不以为耻反以为荣 解:首先按行扫描编号,如果在同一块中(即可以相互攻击),那么将其标为相同的数组,对列也做同样的操作. 然后扫描整张图,如果行编号为a的块与列编号为b的块有公共点,那么将二部图中A集合中a点与B集合中b点相连.最后求出来最大二分匹配数就是答案. (为什么这样做)首先很明显的,二部图中每一条边就对应原图中的一个点,因此,匹配数=边数=最多可放置的战舰数,另外二分图每个点只能匹配一次,对应到原题中就是每一块只能放置一个战舰. 1

HDU 3829 - Cat VS Dog (二分图最大独立集)

题意:动物园有n只猫和m条狗,现在有p个小孩,他们有的喜欢猫,有的喜欢狗,其中喜欢猫的一定不喜欢狗,喜欢狗的一定不喜欢猫.现在管理员要从动物园中移除一些动物,如果一个小孩喜欢的动物留了下来而不喜欢的动物被移走,这个小孩会很高兴.现在问最多可以让多少个小孩高兴. 此题是求二分图最大独立集. 二分图比较明显,但是难在建图.这个题是找到最多的喜欢猫和喜欢狗而不互相冲突的小孩,这样我们将喜欢动物相互冲突的小孩之间连边,问题就变成了求二分图的最大独立集. 在二分图中,最大独立集=顶点数-最大匹配数. 求解

HDU 3289 Cat VS Dog (二分匹配 求 最大独立集)

题意:每个人有喜欢的猫和不喜欢的狗.留下他喜欢的猫他就高心,否则不高心.问最后最多有几个人高心. 思路:二分图求最大匹配 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdlib> 6 #include<string> 7 #include<cmath> 8 #include<

hdu 3829 Cat VS Dog 二分图匹配 最大点独立集

Cat VS Dog Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) Problem Description The zoo have N cats and M dogs, today there are P children visiting the zoo, each child has a like-animal and a dislike-animal, if the

HDU 3639 Hawk-and-Chicken(强连通缩点+反向建图)

http://acm.hdu.edu.cn/showproblem.php?pid=3639 题意: 有一群孩子正在玩老鹰抓小鸡,由于想当老鹰的人不少,孩子们通过投票的方式产生,但是投票有这么一条规则:投票具有传递性,A支持B,B支持C,那么C获得2票(A.B共两票),输出最多能获得的票数是多少张和获得最多票数的人是谁? 思路: 先强连通缩点反向建图,在计算强连通的时候,需要保存每个连通分支的结点个数. 为什么要反向建图呢?因为要寻找票数最多的,那么肯定是入度为0的点,然后dfs计算它的子节点的

HDU 4370 0 or 1(spfa+思维建图+计算最小环)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4370 题目大意:有一个n*n的矩阵Cij(1<=i,j<=n),要找到矩阵Xij(i<=1,j<=n)满足以下条件: 1.X 12+X 13+...X 1n=1  2.X 1n+X 2n+...X n-1n=1  3.for each i (1<i<n), satisfies ∑X ki (1<=k<=n)=∑X ij (1<=j<=n). 举个例子

HDU 3829 Cat VS Dog(最大独立集)

题目大意: 有n只猫,有m只狗.现在有P个学生去参观动物园.每个孩子有喜欢的动物和不喜欢的动物.假如他喜欢猫那么他就一定不喜欢狗(反之亦然). 如果一个孩子喜欢一个动物,那么这个动物不会被移除,若是不喜欢则移除.现在管理员想知道移除哪些动物可以使最大数量的孩子高兴. 输入数据: 输入包含多组测试实例. 第一行是三个数字n, m, p. 接下来p行. 每行 CX, DX 代表他喜欢第X只猫,讨厌第X只狗(反之亦然) 题目思路: 构图思路:我们把所有人进行构图,如果两个人之间有矛盾就建立一条边.然后