Gym - 101915D Largest Group 最大独立集 Or 状态压缩DP

题面
题意:给你N个男生,N个女生,男生与男生之间都是朋友,女生之间也是,再给你m个关系,告诉你哪些男女是朋友,最后问你最多选几个人出来,大家互相是朋友. N最多为20

题解:很显然就像二分图了,男生一边女生一边的,然后一种解法就是

求图的最大独立集,(看起来很巧,实则也是一种套路)

(最大独立集是一个点集,其中任意两点在图中无对应边,对于一般图来说,最大独立集是一个NP完全问题,对于二分图来说最大独立集=|V|-二分图的最大匹配数)

我们本来连边是,所有的朋友关系连边(男女就行了,同性都可以忽略了因为肯定可以)

但我们现在把这个图边连满,然后把有关系的边删掉,再求最大独立集,此时要求他们没有对应边不就是实际上选了那条边了吗

 1 #include<bits/stdc++.h>
 2 #define N 155
 3 int T,n,m,x,y,used[N],g[N][N],val[N],ans;
 4 using namespace std;
 5 int dfs(int x)
 6 {
 7     for (int i=1;i<=n;i++)
 8     {
 9         if (g[x][i]==-1) continue;
10         if (!used[i])
11         {
12             used[i]=1;
13             if (val[i]==-1 || dfs(val[i]))
14             {
15                 val[i]=x;
16                 return 1;
17             }
18         }
19     }
20     return 0;
21 }
22 int main()
23 {
24     scanf("%d",&T);
25     while(T--)
26     {
27         scanf("%d%d",&n,&m);
28         memset(g,0,sizeof(g));
29         memset(val,-1,sizeof(val));
30         while (m--)
31         {
32             scanf("%d%d",&x,&y);
33             g[x][y]=-1;
34         }
35         ans=2*n;
36         for (int i=1;i<=n;i++)
37         {
38             memset(used,0,sizeof(used));
39             ans-=dfs(i);
40         }
41         printf("%d\n",ans);
42     }
43 }

赛后,其他队有人写的是状态压缩dp,哈哈,一看数据范围20,确实可以直接暴力统计答案了,

f[st]表示男生状态为st的时候,女生的状态为什么(st是一个20位的数,f[st]也是哈,每位0,1表示这个人选不选)

题解直接就写在下面代码注释了

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define lld long long
 4 int T,n,m,f[1<<20+1],x,y,ll[50];
 5 int main()
 6 {
 7     scanf("%d",&T);
 8     while (T--)
 9     {
10         scanf("%d%d",&n,&m);
11         int all=1<<n;
12         for (int i=0;i<all;i++) f[i]=0;
13         memset(ll,0,sizeof(ll));
14         while (m--)
15         {
16             scanf("%d%d",&x,&y);
17             ll[x]|=(1<<(y-1));//把x的第y位变成1
18         }
19         int ans=n;
20         f[0]=all-1;
21         for (int st=1;st<all;st++)
22         {
23             int pos=__builtin_ffs(st);//返回x中最后一个为1的位是从后向前的第几位
24             f[st]=f[st^(1<<(pos-1))] & ll[pos];//st的第pos位拿出来取反 然后和这个人pos的好友状态 是否合法
25             ans=max(ans, __builtin_popcount(f[st])+__builtin_popcount(st));//f[st]表示当男生选择集合为st的时候,女生的状态
26         }
27         printf("%d\n",ans);
28      }
29 }

原文地址:https://www.cnblogs.com/qywhy/p/9745048.html

时间: 2024-10-12 21:39:30

Gym - 101915D Largest Group 最大独立集 Or 状态压缩DP的相关文章

Gym - 101915D Largest Group 最大团

给你一个二分图 问你最大团为多大 解一:状压DP 解二:二分图最大匹配 二分图的最大团=补图的最大独立集 二分图最大独立集=二分图定点个数-最大匹配 //Hungary #include<bits/stdc++.h> using namespace std; #define N 50 int useif[N]; //记录y中节点是否使用 0表示没有访问过,1为访问过 int link[N]; //记录当前与y节点相连的x的节点 int mat[N][N]; //记录连接x和y的边,如果i和j之

HDU_3182_Hamburger Magi_状态压缩dp

Hamburger Magi Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 509    Accepted Submission(s): 163 Problem Description In the mysterious forest, there is a group of Magi. Most of them like to eat

Relocation 状态压缩DP

Relocation Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description Emma and Eric are moving to their new house they bought after returning from their honeymoon. Fortunately, they have a few friends helpi

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反

HDU1565(状态压缩dp)

方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8170    Accepted Submission(s): 3095 Problem Description 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数

HDU 3001【状态压缩DP】

题意: 给n个点m条无向边. 要求每个点最多走两次,要访问所有的点给出要求路线中边的权值总和最小. 思路: 三进制状态压缩DP,0代表走了0次,1,2类推. 第一次弄三进制状态压缩DP,感觉重点是对数据的预处理,利用数组分解各个位数,从而达到类似二进制的目的. 然后就是状态的表示,dp[s][i]表示状态s时到达i的最优值. 状态转移也一目了然,不废话. #include<stdio.h> #include<string.h> #include<algorithm> u

Victor and World(spfa+状态压缩dp)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5418 Victor and World Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Others)Total Submission(s): 958    Accepted Submission(s): 431 Problem Description After trying hard fo

poj 3311 Hie with the Pie(状态压缩dp)

Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possible. Unfortunately, due to cutbacks, they can afford to hire only one driver to do the deliveries. He will wait for 1 or more (up to 10) orders to be

HDU--1074(状态压缩DP)

典型的状态压缩DP,给出了每件作业的截止时间和花费,求让老师扣分最少的写作业方式.把完成n种作业用状态2^n-1表示,dp[s]表示 完成状态s时,最小扣分.比如“111”,那么可以由“011”,“110”,“101”转移过来,分别表示选了0,1号作业,1,2号作业,0,2号作业. t[s]表示状态S记录的总时间.dp[s] = min{dp[j]+c[k] - d[k]},其中j = i^(1<<k),0<k<n;pre[s]表示状态s完成时,最末尾完成的作业, #include