博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
3372 选学霸
阅读量:6676 次
发布时间:2019-06-25

本文共 1255 字,大约阅读时间需要 4 分钟。

3372 选学霸

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 大师 Master
 
 
 
题目描述 
Description

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

输入描述 
Input Description

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

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

输出描述 
Output Description

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

样例输入 
Sample Input

4 3 2

1 2

3 4

样例输出 
Sample Output

2

数据范围及提示 
Data Size & Hint

100%的数据N,P<=30000

分类标签 Tags 

 
     
 
题解: 

输入时,采用并查集,把实力相同的人合并到一个集合,在一个循环,统计每个集合的人数,就像是物品

的体积,背包最多的体积不超过m,取与m之差的绝对值最小的那种方案(跑绝对值之差最小的01背包就行)。

AC代码:
#include
using namespace std;const int N=4e5+10;int n,m,k,cnt,fa[N],v[N],belong[N],f[N];int find(int x){ return fa[x]==x?x:fa[x]=find(fa[x]);} int main(){ scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++) fa[i]=i; for(int i=1,x,y;i<=k;i++) scanf("%d%d",&x,&y),fa[find(y)]=find(x); for(int i=1;i<=n;i++){ int t=find(i); if(!belong[t]) v[belong[t]=++cnt]=1; else v[belong[t]]++; } f[0]=1; for(int i=1;i<=cnt;i++){ for(int j=n;j>=v[i];j--){ if(f[j-v[i]]) f[j]=1; } } int minn=0x3f3f3f3f,ans; for(int i=0;i<=n;i++) if(f[i]&&abs(i-m)

 

转载于:https://www.cnblogs.com/shenben/p/5778515.html

你可能感兴趣的文章
遍历js的obj中所有属性得key
查看>>
lua demo
查看>>
iOS开发-UITapGestureRecognizer手势
查看>>
在QTreeWidget中删除QTreeWidgetItem
查看>>
网页引导:jQuery插件实现的页面功能介绍引导页效果
查看>>
【CSS】使用CSS改变超链接样式
查看>>
HTC T328W刷机包 仿三星S5 UI美化 精简 S5落下
查看>>
spring AOP面向切面编程学习笔记
查看>>
Proftp设置虚拟用户(转)
查看>>
基于tiny4412的Linux内核移植(支持device tree)(二)
查看>>
iOS开发网络篇—NSURLConnection基本使用
查看>>
angularjs笔记(二)
查看>>
SQL Server数据库多种方式查找重复记录
查看>>
Target runtime Apache Tomcat v6.0 is not defined.错误解决方法
查看>>
为什么我们要研究中断?【转】
查看>>
tcpdump wireshark 实用过滤表达式(针对ip、协议、端口、长度和内容) 实例介绍...
查看>>
C#.net调用axis2webService
查看>>
NOIP2010乌龟棋[DP 多维状态]
查看>>
Linux 系统中用户切换(su user与 su - user 的区别)
查看>>
微信订阅号消息回复测试
查看>>