题目传送门

开始看到本题完全认为就是个彻头彻尾的并查集,只要把实力相当的人都并到一个集合中,最后再找一共有多少联通块即可。

后来发现这是大错特错的qwq。因为选了一个集合中的某人,那这个集合中所有人就要都选。

理解题意并不透彻:这个集合中的所有人,要么都不选,要么都得选。其实到这里就可以看出,它其实是肥肠满足01背包的性质,每个集合(可以打包看成一个物品)要么选,要么不选,只有两种决策,这个物品的体积和价值都是集合内学生的个数。

然后,这又是一种可行性背包类型:因为题目要求与给定值最接近的选出的学霸数量,所以以f[i]表示选出i个学生是否可行。

转移和01背包类似,之前在USACO中也做过类似的题目,只是当时没太注意了。这类题目看起来一点也不像背包,但是可以这么求解。

其他细节:记录各集合人数的时候最后需要重新路径压缩一下,确保找到最“根”的父亲

     dp赋初值!dp[0]=1;

     因为要找最接近的,所以可能比基准值大一些,也可能比基准值小一些,所以数组和最后枚举求解都开到2*m。

 #include<cstdio>
#include<algorithm> using namespace std; int n,m,k,tot;
int f[],tong[],good[];
bool dp[]; int getf(int x)
{
if(f[x]==x) return x;
else return getf(f[x]);
} int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=n;i++) f[i]=i;
for(int i=;i<=k;i++)
{
int x=,y=;
scanf("%d%d",&x,&y);
int pp=getf(x);
int qq=getf(y);
if(qq!=pp) f[qq]=pp;
}
for(int i=;i<=n;i++)
tong[getf(i)]++;
for(int i=;i<=n;i++)
if(tong[i]) good[++tot]=tong[i];
dp[]=;
for(int i=;i<=tot;i++)
for(int j=*m;j>=good[i];j--)
if(dp[j-good[i]])
dp[j]=;
for(int i=;i<=m;i++)
{
if(dp[m-i])
{
printf("%d",m-i);
return ;
}
if(dp[m+i])
{
printf("%d",m+i);
return ;
}
}
return ;
}

Luogu P2170选学霸【并查集+背包】By cellur925的更多相关文章

  1. [luogu P2170] 选学霸(并查集+dp)

    题目传送门:https://www.luogu.org/problem/show?pid=2170 题目描述 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一 ...

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

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

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

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

  4. poj1417 True Liars[并查集+背包]

    有一点小转化的题,在设计dp状态时还是有点费脑筋的. 地址. 依题意,首先可以知道肯定要扩展域的并查集(明摆着的嘛).一个"好人"域,一个"坏人"域,每句话分两 ...

  5. 西安邀请赛-D(带权并查集+背包)

    题目链接:https://nanti.jisuanke.com/t/39271 题意:给定n个物品,m组限制,每个物品有个伤害值,现在让两个人取完所有物品,要使得两个人取得物品伤害值之和最接近,输出伤 ...

  6. poj1417 带权并查集 + 背包 + 记录路径

    True Liars Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2713   Accepted: 868 Descrip ...

  7. POJ - 1417 并查集+背包

    思路:很简单的种类并查集,利用并查集可以将所有的人分成几个集合,每个集合又分为好人和坏人集合,直接进行背包dp判断有多少种方法可以在取了所有集合并且人数正好凑足p1个好人的方案.dp(i, j)表示前 ...

  8. poj1417(带权并查集+背包DP+路径回溯)

    题目链接:http://poj.org/problem;jsessionid=8C1721AF1C7E94E125535692CDB6216C?id=1417 题意:有p1个天使,p2个恶魔,天使只说 ...

  9. 并查集+背包 【CF741B】 Arpa's weak amphitheater and Mehrdad's valuable Hoses

    Descirption 有n个人,每个人都有颜值bi与体重wi.剧场的容量为W.有m条关系,xi与yi表示xi和yi是好朋友,在一个小组. 每个小组要么全部参加舞会,要么参加人数不能超过1人. 问保证 ...

随机推荐

  1. nfs 挂载错误

    [ 147.080000] svc: failed to register lockdv1 RPC service (errno 146). [ 147.090000] lockd_up: makes ...

  2. Python 学习资料分享

    有同学需要学习 Python,确实,随着人工智能被炒的火热,再加上大数据时代,作为程序员的我们,怎么可能坐得住,必须尝尝鲜,给自己增加一项技能,增加自己的竞争了. 内容定位 这方面的学习资料比较多,本 ...

  3. hadoop eclipse插件生成

    hadoop eclipse插件生成 做了一年的hadoop开发.还没有自动生成过eclipse插件,一直都是在网上下载别人的用,今天有时间,就把这段遗憾补回来,自己生成一下,废话不说,開始了. 本文 ...

  4. python day - 17 面向对象的 类空间 和 组合

    1. 类命名空间 在类的代码中,当python 解释器在 运行的那一刻.就会在内存中开辟一个类空间,在类的空间中会加载静态变量,以及类方法的内存地址. 当类名+()(也就是实例化过程中),内存中会再次 ...

  5. 几个 PHP 的"魔术常量"

    __LINE__ 文件中的当前行号. __FILE__ 文件的完整路径和文件名.如果用在被包含文件中,则返回被包含的文件名.自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径(如果是符 ...

  6. [RK3288][Android6.0] 调试笔记 --- 系统识别不同硬件版本方法【转】

    本文转载自:http://m.blog.csdn.net/kris_fei/article/details/70226451 Platform: RockchipOS: Android 6.0Kern ...

  7. hihocoder #1068 : RMQ-ST算法 ( RMQ算法 O(nlogn)处理 O(1)查询 *【模板】 1)初始化d数组直接读入+计算k值用数学函数log2()==*节约时间 )

    #1068 : RMQ-ST算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在美国旅行了相当长的一段时间之后,终于准备要回国啦!而在回国之前,他们准备 ...

  8. nginx网站日志配置

    用yum安装的nginx的日志默认安装在路径:/var/log/nginx nginx配置文件:/etc/nginx/nginx.conf (总配置文件)/etc/nginx/conf.d/defau ...

  9. HDU - 1875 畅通工程再续(最小生成树)

    d.c个小岛,通过建立桥,使其全部可达.求所有的桥的最小长度和. s.最小生成树,数据改成double就行了 c.Prim算法:cost[a][b]和cost[b][a]都得赋值. /* Prim算法 ...

  10. 如何下载WDK

    随着Windows Vista和Windows Server 2008的相继发布,微软的驱动开发工具也进行了相应的更新换代.原来的驱动开发工具包叫做DDK(Driver Develpment Kit) ...