【codevs3372】选学霸,并查集+可达性DP
2015-12-13 14:16
309 查看
选学霸
时间限制: 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
写在前面:感谢Shallwe的帮助
——————————————————————————————————————————————
思路:用并查集初始化,然后当作可达性背包来做(由于数据比较弱,没有O(15000*30000)的卡人数据)就可以了
代码:
时间限制: 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
写在前面:感谢Shallwe的帮助
——————————————————————————————————————————————
思路:用并查集初始化,然后当作可达性背包来做(由于数据比较弱,没有O(15000*30000)的卡人数据)就可以了
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cstdlib> #include<cmath> using namespace std; int father[30010],num[30010],a[30010];//a数组存放物品标号,num存放每个物品的价值(对于选i来说必须要选的人数) bool f[60010]; int n,m,k,ans; int find(int x) { if (x!=father[x]) father[x]=find(father[x]); return father[x]; } void pd(int x,int y) { if (abs(m-x)<abs(m-y)) ans=x; } main() { int x,y,p,q; int t; scanf("%d%d%d",&n,&m,&k); for (int i=1;i<=n;i++) father[i]=i; for (int i=1;i<=k;i++) { scanf("%d%d",&x,&y); p=find(x);q=find(y); if (p!=q) father[p]=q; } for (int i=1;i<=n;i++) { t=find(i); num[t]++; if (num[t]==1) a[++a[0]]=t; } f[0]=1; for (int i=1;i<=a[0];i++) for (int j=2*m;j>=num[a[i]];j--) f[j]=max(f[j-num[a[i]]],f[j]); for (int i=m;i>=0;i--) if (f[i]) {ans=i;break;} for (int i=m;i<=2*m;i++) if (f[i]) pd(i,ans),printf("%d",ans),exit(0); printf("%d",ans); }
相关文章推荐
- 欧拉函数与欧拉定理
- printf特殊用法
- VirtualBox备忘=>LTS
- android 中popupWindow与AlertDialog区别
- 悟透JavaScript(理解JS面向对象的好文章)
- Linux 下C语言 指针学习 二 (数组与指针)
- 工厂模式
- 建立多分类logistic模型的R语言代码
- iOS多线程开发——NSOperation/NSOperationQueue浅析
- Canvas画图
- 对称矩阵的压缩存储及基本运算
- 工厂模式
- 工厂模式
- 输入一串数字输出最大的数字
- 使用Fluent API进行属性映射【Code-First系列】
- poj1852 Ants (模拟)
- PAT程序设计练习——甲级1001(标准格式化数字)
- 白盒测试技术含量不一定比黑盒测试高
- JSP验证码动态生成方法
- start booting from usb device,U盘安装ubuntu无法引导系统