[luogu P2170] 选学霸(并查集+dp)
题目传送门:https://www.luogu.org/problem/show?pid=2170
题目描述
老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一部分没有,同学们就会抗议。所以老师想请你帮他求出他该选多少学霸,才能既不让同学们抗议,又与原来的M尽可能接近
输入输出格式
输入格式:
第一行,三个正整数N,M,K。
第2...K行,每行2个数,表示一对实力相当的人的编号(编号为1…N)
输出格式:
一行,表示既不让同学们抗议,又与原来的M尽可能接近的选出学霸的数目。(如果有两种方案与M的差的绝对值相等,选较小的一种:)
输入输出样例
4 3 2
1 2
3 4
2
说明
100%的数据N,P<=20000
利用并查集将所有实力相当的人并到一个集合当中,把每个集合看做一个物品,物品的价值为每个集合中的人数,进而转换为01背包问题,由于是使价值总和与m的差的绝对值最小,于是利用2*m容量的背包,dp即可。
状态转移方程:f[j]=max(f[j],f[j-cnt[i]]+cnt[i])。
从m开始向两边扫描寻找答案即可得解。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std; int n,m,k,tot,que[],cnt[],father[],f[]; int gf(int x) {
if (father[x]==x) return x;
father[x]=gf(father[x]);
return father[x];
} int main() {
scanf("%d%d%d",&n,&m,&k);
for (int i=; i<=n; i++) father[i]=i;
for (int i=; i<=k; i++) {
int x,y;
scanf("%d%d",&x,&y);
int fx=gf(x);
int fy=gf(y);
if (fx!=fy) father[fx]=fy;
}
for (int i=; i<=n; i++) cnt[gf(i)]++;
for (int i=; i<=n; i++) if (cnt[i]) que[++tot]=i;
for (int i=; i<=tot; i++) {
int cur=que[i];
for (int j=*m; j>=cnt[cur]; j--)
f[j]=max(f[j],f[j-cnt[cur]]+cnt[cur]);
}
for (int i=; i<=m; i++) {
if (f[m-i]==m-i) {
printf("%d",m-i);
break;
}
if (f[m+i]==m+i) {
printf("%d",m+i);
break;
}
}
}
[luogu P2170] 选学霸(并查集+dp)的更多相关文章
- Luogu P2170选学霸【并查集+背包】By cellur925
题目传送门 开始看到本题完全认为就是个彻头彻尾的并查集,只要把实力相当的人都并到一个集合中,最后再找一共有多少联通块即可. 后来发现这是大错特错的qwq.因为选了一个集合中的某人,那这个集合中所有人就 ...
- poj1417(种类并查集+dp)
题目:http://poj.org/problem?id=1417 题意:输入三个数m, p, q 分别表示接下来的输入行数,天使数目,恶魔数目: 接下来m行输入形如x, y, ch,ch为yes表示 ...
- [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\)对人实力相当,如果实力相当的人中,一部分被选上,另一部 ...
- POJ 1417 True Liars(种类并查集+dp背包问题)
题目大意: 一共有p1+p2个人,分成两组,一组p1,一组p2.给出N个条件,格式如下: x y yes表示x和y分到同一组,即同是好人或者同是坏人. x y no表示x和y分到不同组,一个为好人,一 ...
- poj1417 true liars(并查集 + DP)详解
这个题做了两天了.首先用并查集分类是明白的, 不过判断是否情况唯一刚开始用的是搜索.总是超时. 后来看别人的结题报告, 才恍然大悟判断唯一得用DP. 题目大意: 一共有p1+p2个人,分成两组,一组p ...
- 【POJ1417】【带标记并查集+DP】True Liars
Description After having drifted about in a small boat for a couple of days, Akira Crusoe Maeda was ...
- P2170 选学霸
传送门 思路: ① 可以把每个学生都看作点,而那些实力相同的学生就处在同一个连通块内,因为连通块内的同学要么都取,要么不取,所以可以将连通块缩成一个点.只需用并查集维护每个连通块的大小. ② 接着采取 ...
- POJ 1417 - True Liars - [带权并查集+DP]
题目链接:http://poj.org/problem?id=1417 Time Limit: 1000MS Memory Limit: 10000K Description After having ...
随机推荐
- 学好C++必须要注意的十八个问题
转自 http://blog.chinaunix.net/uid-7396260-id-2056691.html 一.#include "filename.h"和#i nclud ...
- iPhone 6/6 Plus国行版开卖当日抢购攻略
在距离苹果首批发售时隔一个月也就是北京时间10月17日,苹果iPhone 6.iPhone 6 Plus终于也要在中国大陆开卖,众多国内用户终于有机会安排自己的购机计划.据不完全数据显示,目前iPho ...
- SharePoint表单和工作流 - Nintex篇(三)
博客地址 http://blog.csdn.net/foxdave 接上篇点击打开链接 跳转到网站设置的Nintex设置,我们来挨个了解一下,这里面一共有15项设置,本篇我们先了解前7个. " ...
- SharePoint 2010 BCS - 简单实例(一)数据源添加
博客地址 http://blog.csdn.net/foxdave 本篇基于SharePoint 2010 Foundation. 我的数据库中有一个病人信息表Patient,现在我就想把这个表中的数 ...
- Oracle Data Integrator与OWB的集成及迁移
v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...
- 实例化(用new的方式)创建一个对象的顺序
父类静态块--->子类静态块----->父类普通代码块----->父类构造方法------->子类普通代码块----->子类构造方法 如果父类构造方法中调用的非priva ...
- C# 对MongoDB 进行增删改查的简单操作 (转)
运用到的MongoDB支持的C#驱动,当前版本为1.6.0 下载地址:https://github.com/mongodb/mongo-csharp-driver/downloads 1,连接数据库 ...
- 高效的iOS宏定义
iOS开发过程中使用一些常用的宏可以提高开发效率,提高代码的重用性:将这些宏放到一个头文件里然后再放到工程中的-Prefix.pch文件中(或者直接放到-Prefix.pch中)直接可以使用,灰常方便 ...
- 12-28 显示团购数据界面的搭建,cell的自定义方面的知识总结
1.通过plist加载模型数据 2.controller中懒加载数据 3.设置tableView的数据源 4.写数据源的方法 5.观察演示项目,分析通过默认的cell的4种现实方式,无法实现要想要的现 ...
- Sticks_dfs
Description George took sticks of the same length and cut them randomly until all parts became at mo ...