Luogu P2170选学霸【并查集+背包】By cellur925
开始看到本题完全认为就是个彻头彻尾的并查集,只要把实力相当的人都并到一个集合中,最后再找一共有多少联通块即可。
后来发现这是大错特错的qwq。因为选了一个集合中的某人,那这个集合中所有人就要都选。
理解题意并不透彻:这个集合中的所有人,要么都不选,要么都得选。其实到这里就可以看出,它其实是肥肠满足01背包的性质,每个集合(可以打包看成一个物品)要么选,要么不选,只有两种决策,这个物品的体积和价值都是集合内学生的个数。
然后,这又是一种可行性背包类型:因为题目要求与给定值最接近的选出的学霸数量,所以以f[i]表示选出i个学生是否可行。
转移和01背包类似,之前在USACO中也做过类似的题目,只是当时没太注意了。这类题目看起来一点也不像背包,但是可以这么求解。
其他细节:记录各集合人数的时候最后需要重新路径压缩一下,确保找到最“根”的父亲
dp赋初值!dp[0]=1;
因为要找最接近的,所以可能比基准值大一些,也可能比基准值小一些,所以数组和最后枚举求解都开到2*m。
#include<cstdio>
#include<algorithm> using namespace std; int n,m,k,tot;
int f[],tong[],good[];
bool dp[]; int getf(int x)
{
if(f[x]==x) return x;
else return getf(f[x]);
} int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=n;i++) f[i]=i;
for(int i=;i<=k;i++)
{
int x=,y=;
scanf("%d%d",&x,&y);
int pp=getf(x);
int qq=getf(y);
if(qq!=pp) f[qq]=pp;
}
for(int i=;i<=n;i++)
tong[getf(i)]++;
for(int i=;i<=n;i++)
if(tong[i]) good[++tot]=tong[i];
dp[]=;
for(int i=;i<=tot;i++)
for(int j=*m;j>=good[i];j--)
if(dp[j-good[i]])
dp[j]=;
for(int i=;i<=m;i++)
{
if(dp[m-i])
{
printf("%d",m-i);
return ;
}
if(dp[m+i])
{
printf("%d",m+i);
return ;
}
}
return ;
}
Luogu P2170选学霸【并查集+背包】By cellur925的更多相关文章
- [luogu P2170] 选学霸(并查集+dp)
题目传送门:https://www.luogu.org/problem/show?pid=2170 题目描述 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一 ...
- [BZOJ4569] [Luogu 3295] [SCOI2016]萌萌哒(并查集+倍增)
[BZOJ4569] [Luogu 3295] [SCOI2016]萌萌哒(并查集+倍增) 题面 有一个n位的十进制数a(无前导0),给出m条限制,每条限制\((l_1,r_1,l_2,r_2)(保证 ...
- 『题解』洛谷P2170 选学霸
更好的阅读体验 Portal Portal1: Luogu Description 老师想从\(N\)名学生中选\(M\)人当学霸,但有\(K\)对人实力相当,如果实力相当的人中,一部分被选上,另一部 ...
- poj1417 True Liars[并查集+背包]
有一点小转化的题,在设计dp状态时还是有点费脑筋的. 地址. 依题意,首先可以知道肯定要扩展域的并查集(明摆着的嘛).一个"好人"域,一个"坏人"域,每句话分两 ...
- 西安邀请赛-D(带权并查集+背包)
题目链接:https://nanti.jisuanke.com/t/39271 题意:给定n个物品,m组限制,每个物品有个伤害值,现在让两个人取完所有物品,要使得两个人取得物品伤害值之和最接近,输出伤 ...
- poj1417 带权并查集 + 背包 + 记录路径
True Liars Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2713 Accepted: 868 Descrip ...
- POJ - 1417 并查集+背包
思路:很简单的种类并查集,利用并查集可以将所有的人分成几个集合,每个集合又分为好人和坏人集合,直接进行背包dp判断有多少种方法可以在取了所有集合并且人数正好凑足p1个好人的方案.dp(i, j)表示前 ...
- poj1417(带权并查集+背包DP+路径回溯)
题目链接:http://poj.org/problem;jsessionid=8C1721AF1C7E94E125535692CDB6216C?id=1417 题意:有p1个天使,p2个恶魔,天使只说 ...
- 并查集+背包 【CF741B】 Arpa's weak amphitheater and Mehrdad's valuable Hoses
Descirption 有n个人,每个人都有颜值bi与体重wi.剧场的容量为W.有m条关系,xi与yi表示xi和yi是好朋友,在一个小组. 每个小组要么全部参加舞会,要么参加人数不能超过1人. 问保证 ...
随机推荐
- nfs 挂载错误
[ 147.080000] svc: failed to register lockdv1 RPC service (errno 146). [ 147.090000] lockd_up: makes ...
- Python 学习资料分享
有同学需要学习 Python,确实,随着人工智能被炒的火热,再加上大数据时代,作为程序员的我们,怎么可能坐得住,必须尝尝鲜,给自己增加一项技能,增加自己的竞争了. 内容定位 这方面的学习资料比较多,本 ...
- hadoop eclipse插件生成
hadoop eclipse插件生成 做了一年的hadoop开发.还没有自动生成过eclipse插件,一直都是在网上下载别人的用,今天有时间,就把这段遗憾补回来,自己生成一下,废话不说,開始了. 本文 ...
- python day - 17 面向对象的 类空间 和 组合
1. 类命名空间 在类的代码中,当python 解释器在 运行的那一刻.就会在内存中开辟一个类空间,在类的空间中会加载静态变量,以及类方法的内存地址. 当类名+()(也就是实例化过程中),内存中会再次 ...
- 几个 PHP 的"魔术常量"
__LINE__ 文件中的当前行号. __FILE__ 文件的完整路径和文件名.如果用在被包含文件中,则返回被包含的文件名.自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径(如果是符 ...
- [RK3288][Android6.0] 调试笔记 --- 系统识别不同硬件版本方法【转】
本文转载自:http://m.blog.csdn.net/kris_fei/article/details/70226451 Platform: RockchipOS: Android 6.0Kern ...
- hihocoder #1068 : RMQ-ST算法 ( RMQ算法 O(nlogn)处理 O(1)查询 *【模板】 1)初始化d数组直接读入+计算k值用数学函数log2()==*节约时间 )
#1068 : RMQ-ST算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在美国旅行了相当长的一段时间之后,终于准备要回国啦!而在回国之前,他们准备 ...
- nginx网站日志配置
用yum安装的nginx的日志默认安装在路径:/var/log/nginx nginx配置文件:/etc/nginx/nginx.conf (总配置文件)/etc/nginx/conf.d/defau ...
- HDU - 1875 畅通工程再续(最小生成树)
d.c个小岛,通过建立桥,使其全部可达.求所有的桥的最小长度和. s.最小生成树,数据改成double就行了 c.Prim算法:cost[a][b]和cost[b][a]都得赋值. /* Prim算法 ...
- 如何下载WDK
随着Windows Vista和Windows Server 2008的相继发布,微软的驱动开发工具也进行了相应的更新换代.原来的驱动开发工具包叫做DDK(Driver Develpment Kit) ...