题目传送门:https://www.luogu.org/problem/show?pid=2170

题目描述

老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一部分没有,同学们就会抗议。所以老师想请你帮他求出他该选多少学霸,才能既不让同学们抗议,又与原来的M尽可能接近

输入输出格式

输入格式:

第一行,三个正整数N,M,K。

第2...K行,每行2个数,表示一对实力相当的人的编号(编号为1…N)

输出格式:

一行,表示既不让同学们抗议,又与原来的M尽可能接近的选出学霸的数目。(如果有两种方案与M的差的绝对值相等,选较小的一种:)

输入输出样例

输入样例#1:

4 3 2
1 2
3 4
输出样例#1:

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)的更多相关文章

  1. Luogu P2170选学霸【并查集+背包】By cellur925

    题目传送门 开始看到本题完全认为就是个彻头彻尾的并查集,只要把实力相当的人都并到一个集合中,最后再找一共有多少联通块即可. 后来发现这是大错特错的qwq.因为选了一个集合中的某人,那这个集合中所有人就 ...

  2. poj1417(种类并查集+dp)

    题目:http://poj.org/problem?id=1417 题意:输入三个数m, p, q 分别表示接下来的输入行数,天使数目,恶魔数目: 接下来m行输入形如x, y, ch,ch为yes表示 ...

  3. [BZOJ4569] [Luogu 3295] [SCOI2016]萌萌哒(并查集+倍增)

    [BZOJ4569] [Luogu 3295] [SCOI2016]萌萌哒(并查集+倍增) 题面 有一个n位的十进制数a(无前导0),给出m条限制,每条限制\((l_1,r_1,l_2,r_2)(保证 ...

  4. 『题解』洛谷P2170 选学霸

    更好的阅读体验 Portal Portal1: Luogu Description 老师想从\(N\)名学生中选\(M\)人当学霸,但有\(K\)对人实力相当,如果实力相当的人中,一部分被选上,另一部 ...

  5. POJ 1417 True Liars(种类并查集+dp背包问题)

    题目大意: 一共有p1+p2个人,分成两组,一组p1,一组p2.给出N个条件,格式如下: x y yes表示x和y分到同一组,即同是好人或者同是坏人. x y no表示x和y分到不同组,一个为好人,一 ...

  6. poj1417 true liars(并查集 + DP)详解

    这个题做了两天了.首先用并查集分类是明白的, 不过判断是否情况唯一刚开始用的是搜索.总是超时. 后来看别人的结题报告, 才恍然大悟判断唯一得用DP. 题目大意: 一共有p1+p2个人,分成两组,一组p ...

  7. 【POJ1417】【带标记并查集+DP】True Liars

    Description After having drifted about in a small boat for a couple of days, Akira Crusoe Maeda was ...

  8. P2170 选学霸

    传送门 思路: ① 可以把每个学生都看作点,而那些实力相同的学生就处在同一个连通块内,因为连通块内的同学要么都取,要么不取,所以可以将连通块缩成一个点.只需用并查集维护每个连通块的大小. ② 接着采取 ...

  9. POJ 1417 - True Liars - [带权并查集+DP]

    题目链接:http://poj.org/problem?id=1417 Time Limit: 1000MS Memory Limit: 10000K Description After having ...

随机推荐

  1. 配置Java环境-20160613

    http://jingyan.baidu.com/article/870c6fc33e62bcb03fe4be90.html   1.安装JDK,参照目录   在D:\Program Files\ec ...

  2. C++全局变量的声明和定义

    (1)编译单元(模块)     在VC或VS上编写完代码,点击编译按钮准备生成exe文件时,编译器做了两步工作: 第一步,将每个.cpp(.c)和相应的.h文件编译成obj文件: 第二步,将工程中所有 ...

  3. XCode 自动化打包总结

    最近一个礼拜折腾xcode 中ipa 自动化打包,对我来说也说是磕磕碰碰.毕竟对mac下的命令行模式完全不熟悉.而且我们的项目是基于cordova的一个项目. 之前我自己对cordova 项目的命令行 ...

  4. php中的include()的使用技巧

    php中的include()的使用技巧 include() 语句包括并运行指定文件. 以下文档也适用于 require().这两种结构除了在如何处理失败之外完全一样.include() 产生一个警告而 ...

  5. hadoop启动jobhistoryserver

    hadoop启动jobhistoryserver来实现web查看作业的历史运行情况,由于在启动hdfs和Yarn进程之后,jobhistoryserver进程并没有启动,需要手动启动,启动的方法是通过 ...

  6. FZU1683 矩阵

    //Accepted 220 KB 359 ms #include <cstdio> #include <cstring> ; int pp; struct matrix { ...

  7. How to Avoid OOM in Android

    1.use java reference(strong soft weak phantom) 2.use android:largeHeap="true" above or VMR ...

  8. hdoj-2033

    A+B系列: #include "stdio.h"int main(){ int a[3],b[3],c[3],i,n,j,flag; while(~scanf("%d& ...

  9. mysql innoDB 与 myISAM

    转载文章 出处  http://www.pureweber.com/article/myisam-vs-innodb/ 使用MySQL当然会接触到MySQL的存储引擎,在新建数据库和新建数据表的时候都 ...

  10. 算法导论 第六章 思考题 6-3 d叉堆

    d叉堆的实现相对于二叉堆变化不大,首先看它如何用数组表示. 考虑一个索引从1开始的数组,一个结点i最多可以有d个子结点,编号从id - (d - 2) 到 id + 1. 从而可以知道一个结点i的父结 ...