这一道题,由于他说,“如果实力相当的人中,一部分被选上,另一部分没有,同学们就会抗议。”而要求“既不让同学们抗议,又与原来的M尽可能接近”。因此,我们要对实力相当的一组同学必须全部选择。所以,我们需要先使用一个并查集,对这个无向图进行“缩点”,存下每一组学霸的人的数量。

我们在并查集的Union操作中,可以顺带就把每一组的学霸也Union过去,具体实现看代码。

然后,我们得到一些组的学霸。然后,我们把它转化成一个装箱问题。如果有可以刚好选满的,我们就把他和Min比较,如果比Min小,我们就记录下来。至于题目要求的“。(如果有两种方案与M的差的绝对值相等,选较小的一种:)”,其实可以很自然地。因为两次相等的话,前面就已经标记过了,不会在执行后面的了。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define rep(i,a,n) for(register int i=(a);i<=(n);++i)
#define per(i,a,n) for(register int i=(a);i>=(n);--i)
#define fec(i,x) for(register int i=head[x];i;i=Next[i])
#define debug(x) printf("debug:%s=%d\n",#x,x)
#define mem(a,x) memset(a,x,sizeof(a))
template<typename A>inline void read(A&a){a=0;int f=1,c=0;while(c<'0'||c>'9'){c=getchar();if(c=='-')f*=-1;}while(c>='0'&&c<='9'){a=a*10+c-'0';c=getchar();}a*=f;}
template<typename A,typename B>inline void read(A&a,B&b){read(a);read(b);}
template<typename A,typename B,typename C>inline void read(A&a,B&b,C&c){read(a);read(b);read(c);}
template<typename A>A gcd(const A&m,const A&n){return m%n==0?n:gcd(n,m%n);} const int maxn=20000+7,INF=0x7fffffff;
int n,m,k;
int x,y,ans=INF,Min=INF;
int father[maxn];
int f[maxn];
int cnt[maxn],tot;
int num[maxn]; int find(int x){
return father[x]==x?x:father[x]=find(father[x]);
} inline void unionn(int x,int y){
int xx=find(x),yy=find(y);
if(xx==yy)return;//这一句话非常重要!如果没有这句话,若xx==yy,cnt[xx]就会被重复计算以后被清零!
father[yy]=xx;
cnt[xx]+=cnt[yy];
cnt[yy]=0;
} inline void UFS_init(){
rep(i,1,n)father[i]=i,cnt[i]=1;
} void CC(){
rep(i,1,n)if(cnt[i])num[++tot]=cnt[i];
} void dp(){
rep(i,1,tot)
per(j,n,num[i])
f[j]=max(f[j],f[j-num[i]]+num[i]);
} void Init(){
read(n,m,k);
UFS_init();
rep(i,1,k){
read(x,y);
unionn(x,y);
}
} void Work(){
CC();
dp();
rep(i,0,n)if(f[i]==i&&abs(f[i]-m)<Min)Min=abs(f[i]-m),ans=f[i];//注意从零开始循环,0也是一个正解!
printf("%d\n",ans);
} int main(){
Init();
Work();
return 0;
}

最新文章

  1. 参加SFDC的感触
  2. cocos2dx骨骼动画Armature源码分析(一)
  3. Bootstrap 3 模态框播放视频
  4. [Leetcode][JAVA] Flatten Binary Tree to Linked List
  5. A.Kaw矩阵代数初步学习笔记 8. Gauss-Seidel Method
  6. 微信支付.NET版开发总结(JS API),好多坑,适当精简
  7. 2014 Super Training #10 C Shadow --SPFA/随便搞/DFS
  8. C# 自定义排序
  9. c语言结构体中的冒号的用法
  10. HDU 1853Cyclic Tour(网络流之最小费用流)
  11. 在Win7的IIS上搭建FTP服务及用户授权
  12. gulp插件大全
  13. JPA之常用 基本注解
  14. 实现Windows程序的数据的绑定
  15. WeihanLi.Npoi
  16. 跨JavaScript对象作用域调用setInterval方法
  17. spring+springmvc+mybatis构建系统
  18. Linux 下挂载新硬盘方法
  19. C++ primer ch6 函数基础-1
  20. TOJ5398: 签到大富翁(简单模拟) and TOJ 5395: 大于中值的边界元素(数组的应用)

热门文章

  1. SPFA的两个优化
  2. Python_003(字符串的神操作)
  3. Linux下MySQL 5.5的修改字符集编码为UTF8(彻底解决中文乱码问题)
  4. Fiddler正则匹配调试接口示例
  5. iOS打印各种类型数据
  6. RabbitMq(7)消息延时推送
  7. 通过VLC的ActiveX进行二次开发,实现一个多媒体播放器 2011-04-10 00:57:23
  8. Socket错误详解及处理方法
  9. python 微服务方案
  10. 通过queue实现前端的被动接收