[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 ...
随机推荐
- 配置Java环境-20160613
http://jingyan.baidu.com/article/870c6fc33e62bcb03fe4be90.html 1.安装JDK,参照目录 在D:\Program Files\ec ...
- C++全局变量的声明和定义
(1)编译单元(模块) 在VC或VS上编写完代码,点击编译按钮准备生成exe文件时,编译器做了两步工作: 第一步,将每个.cpp(.c)和相应的.h文件编译成obj文件: 第二步,将工程中所有 ...
- XCode 自动化打包总结
最近一个礼拜折腾xcode 中ipa 自动化打包,对我来说也说是磕磕碰碰.毕竟对mac下的命令行模式完全不熟悉.而且我们的项目是基于cordova的一个项目. 之前我自己对cordova 项目的命令行 ...
- php中的include()的使用技巧
php中的include()的使用技巧 include() 语句包括并运行指定文件. 以下文档也适用于 require().这两种结构除了在如何处理失败之外完全一样.include() 产生一个警告而 ...
- hadoop启动jobhistoryserver
hadoop启动jobhistoryserver来实现web查看作业的历史运行情况,由于在启动hdfs和Yarn进程之后,jobhistoryserver进程并没有启动,需要手动启动,启动的方法是通过 ...
- FZU1683 矩阵
//Accepted 220 KB 359 ms #include <cstdio> #include <cstring> ; int pp; struct matrix { ...
- How to Avoid OOM in Android
1.use java reference(strong soft weak phantom) 2.use android:largeHeap="true" above or VMR ...
- hdoj-2033
A+B系列: #include "stdio.h"int main(){ int a[3],b[3],c[3],i,n,j,flag; while(~scanf("%d& ...
- mysql innoDB 与 myISAM
转载文章 出处 http://www.pureweber.com/article/myisam-vs-innodb/ 使用MySQL当然会接触到MySQL的存储引擎,在新建数据库和新建数据表的时候都 ...
- 算法导论 第六章 思考题 6-3 d叉堆
d叉堆的实现相对于二叉堆变化不大,首先看它如何用数组表示. 考虑一个索引从1开始的数组,一个结点i最多可以有d个子结点,编号从id - (d - 2) 到 id + 1. 从而可以知道一个结点i的父结 ...