CODEVS【3372】选学霸
老师想从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<=30000
实力相当的人要尽量选上,因此我们可以利用并查集把实力相当的人合并,每个集中的老大都有自己的盟友(实力相当的人)(第i个人盟友个数用w[i]表示,初始化w[i]=1),当合并两个集时(f[a]=b),要注意把a的盟友同时合并给b,即w[b]+=w[a],a的盟友自然成了b的盟友,a现在只是一个小喽罗,所以w[a]=0;现在开始枚举w[i]不为0的人,则可以把一个个集看作一个个团队(也可以是单人团队),w[i]表示团队人的个数,++k,最终k表示团队的个数。问题转化为了01背包问题。但是注意此问题要求的是差的绝对值最小的值,所以可以从0开始向两边枚举(枚举dp[m-i]是否等于m-i,dp[m+i]是否等于m+i),第一个枚举到的值输出即可。
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
#include<stack>
#define maxn 30000+50
#define inf 0x7fffffff
#define xiao 1e-9
using namespace std;
int f[maxn],w[maxn],a[maxn],dp[*maxn];
int find(int x)
{
if(f[x]==x) return x;
else return find(f[x]);
}
int main()
{
int n,m,k,b,x;
cin>>n>>m>>k;
for(int i=;i<=n;++i){f[i]=i;w[i]=;}
for(int i=;i<=k;++i)
{
scanf("%d%d",&x,&b);
int fa=find(x),fb=find(b);
if(fa!=fb)
{
f[x]=b;
w[b]+=w[x];
w[x]=;
}
}
k=;
for(int i=;i<=n;++i)
{
if(w[i]!=) a[++k]=w[i];
}
for(int i=;i<=k;++i)
{
for(int j=*m+;j>=a[i];--j)
{
dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
}
}
for(int i=;i<=m;++i)
{
if(dp[m-i]==m-i){cout<<m-i;break;}
if(dp[m+i]==m+i) {cout<<m+i;break;}
}
return ;
}
选学霸
CODEVS【3372】选学霸的更多相关文章
- codevs 3372 选学霸
3372 选学霸 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果 ...
- codevs——3372 选学霸(背包)
题目等级 : 大师 Master 时间限制: 1 s 空间限制: 128000 KB 题解 题目描述 Description 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实 ...
- codevs 3372 选学霸(hash+并查集+多重背包)
先通过并查集处理出来有多少种不同的集合,每一个集合有多少人.一定要不要忘记了与别的没有联系的独立点. 并查集的时候能够通过hash处理出来每一个数目同样的集合的个数. 这样以人数为权值.个数为限制进行 ...
- codevs3370 选学霸(背包dp,并查集)
3372 选学霸 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 老师想从N名学生中选M人当学霸,但有K对人实力相 ...
- 选学霸(codevs 3372)
题目描述 Description 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一部分没有,同学们就会抗议.所以老师想请你帮他求出他该选多少学霸,才能既不让同 ...
- [luogu P2170] 选学霸(并查集+dp)
题目传送门:https://www.luogu.org/problem/show?pid=2170 题目描述 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一 ...
- 「LuoguP2170」 选学霸(01背包
Description 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一部分没有,同学们就会抗议.所以老师想请你帮他求出他该选多少学霸,才能既不让同学们抗议, ...
- Luogu P2170选学霸【并查集+背包】By cellur925
题目传送门 开始看到本题完全认为就是个彻头彻尾的并查集,只要把实力相当的人都并到一个集合中,最后再找一共有多少联通块即可. 后来发现这是大错特错的qwq.因为选了一个集合中的某人,那这个集合中所有人就 ...
- 『题解』洛谷P2170 选学霸
更好的阅读体验 Portal Portal1: Luogu Description 老师想从\(N\)名学生中选\(M\)人当学霸,但有\(K\)对人实力相当,如果实力相当的人中,一部分被选上,另一部 ...
随机推荐
- Java读取各种文件格式内容
所需的jar包哦也不要太记得了,大家可以搜搜,直接上代码: import java.io.BufferedInputStream; import java.io.File; import java.i ...
- window.onload和$(docunment).ready的区别
浏览器加载完DOM后,会通过javascript为DOM元素添加事件,在javascript中,通常使用window.onload()方法. 在jquery中,则使用$(document).ready ...
- RPC框架 - thrift 客户端
-------客户端程序 ------ 下载 下载 thrift 源代码包 下载 thrift 的bin包 准备描述文件(使用源代码包的示例文件) \thrift-0.10.0\tu ...
- python爬虫入门八:多进程/多线程
什么是多线程/多进程 引用虫师的解释: 计算机程序只不过是磁盘中可执行的,二进制(或其它类型)的数据.它们只有在被读取到内存中,被操作系统调用的时候才开始它们的生命期. 进程(有时被称为重量级进程)是 ...
- 2017 United Kingdom and Ireland Programming(Gym - 101606)
题目很水.睡过了迟到了一个小时,到达战场一看,俩队友AC五个了.. 就只贴我补的几个吧. B - Breaking Biscuits Gym - 101606B 旋转卡壳模板题.然后敲错了. 代码是另 ...
- 模拟:HDU1034-Candy Sharing Game
解题心得: 1.直接模拟每一次分一半就行了,模拟过程,记录轮数,但是也看到有些大神使用的是链表,估计链表才是真的做法吧. 题目: Candy Sharing Game Time Limit: 2000 ...
- HTML插入文件链接(如音乐,照片)
html中插入音频.H5的标签 src为本地 <audio controls="> <source src="韩庚 - I Don't Give A 屑.mp3& ...
- mysql-update时where条件无索引锁全表
1 5.3日数据处理需求 UPDATE md_meter set warranty_end_date = DATE_ADD(warranty_begin_date,INTERVAL 10 ...
- Unity 与Mono和.Net的关系
一.分析 首先,我们要知道Unity,Mono,.Net 三者的关系.需要简单说一下.Net. .Net拥有跨语言,跨平台性. 跨语言:就是只要是面向.Net平台的编程语言,用其中一种语言编写的类型就 ...
- Thread和Runnable的子类调用
实现线程的两种方式: 继承Thread类. 实现Runnable接口. 下面是一个小案例: public class Thread和Runnable { public static void main ...