Luogu P2170选学霸【并查集+背包】By cellur925
开始看到本题完全认为就是个彻头彻尾的并查集,只要把实力相当的人都并到一个集合中,最后再找一共有多少联通块即可。
后来发现这是大错特错的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的更多相关文章
- [luogu P2170] 选学霸(并查集+dp)
题目传送门:https://www.luogu.org/problem/show?pid=2170 题目描述 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一 ...
- [BZOJ4569] [Luogu 3295] [SCOI2016]萌萌哒(并查集+倍增)
[BZOJ4569] [Luogu 3295] [SCOI2016]萌萌哒(并查集+倍增) 题面 有一个n位的十进制数a(无前导0),给出m条限制,每条限制\((l_1,r_1,l_2,r_2)(保证 ...
- 『题解』洛谷P2170 选学霸
更好的阅读体验 Portal Portal1: Luogu Description 老师想从\(N\)名学生中选\(M\)人当学霸,但有\(K\)对人实力相当,如果实力相当的人中,一部分被选上,另一部 ...
- poj1417 True Liars[并查集+背包]
有一点小转化的题,在设计dp状态时还是有点费脑筋的. 地址. 依题意,首先可以知道肯定要扩展域的并查集(明摆着的嘛).一个"好人"域,一个"坏人"域,每句话分两 ...
- 西安邀请赛-D(带权并查集+背包)
题目链接:https://nanti.jisuanke.com/t/39271 题意:给定n个物品,m组限制,每个物品有个伤害值,现在让两个人取完所有物品,要使得两个人取得物品伤害值之和最接近,输出伤 ...
- poj1417 带权并查集 + 背包 + 记录路径
True Liars Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2713 Accepted: 868 Descrip ...
- POJ - 1417 并查集+背包
思路:很简单的种类并查集,利用并查集可以将所有的人分成几个集合,每个集合又分为好人和坏人集合,直接进行背包dp判断有多少种方法可以在取了所有集合并且人数正好凑足p1个好人的方案.dp(i, j)表示前 ...
- poj1417(带权并查集+背包DP+路径回溯)
题目链接:http://poj.org/problem;jsessionid=8C1721AF1C7E94E125535692CDB6216C?id=1417 题意:有p1个天使,p2个恶魔,天使只说 ...
- 并查集+背包 【CF741B】 Arpa's weak amphitheater and Mehrdad's valuable Hoses
Descirption 有n个人,每个人都有颜值bi与体重wi.剧场的容量为W.有m条关系,xi与yi表示xi和yi是好朋友,在一个小组. 每个小组要么全部参加舞会,要么参加人数不能超过1人. 问保证 ...
随机推荐
- background-size使用参考指南
语法:background-size :[ <length> | <percentage> | auto ]{1,2} | cover | contain相关属性: backg ...
- MVC上传文件并模拟进度条
进度条样式和JS <style type="text/css"> .spa { font-size: 12px; color: #0066ff; } .put { fo ...
- 为什么说JAVA中要慎重使用继承 C# 语言历史版本特性(C# 1.0到C# 8.0汇总) SQL Server事务 事务日志 SQL Server 锁详解 软件架构之 23种设计模式 Oracle与Sqlserver:Order by NULL值介绍 asp.net MVC漏油配置总结
为什么说JAVA中要慎重使用继承 这篇文章的主题并非鼓励不使用继承,而是仅从使用继承带来的问题出发,讨论继承机制不太好的地方,从而在使用时慎重选择,避开可能遇到的坑. JAVA中使用到继承就会有两 ...
- VLFeat中SIFT特征点检测
本代码使用VLFeat库中的函数对一幅图像进行了SIFT检测 需要事先配置好VLFeat和OpenCV,VLFeat的配置参考前一篇博文,OpenCV的配置网上一大堆,自己去百度 #include & ...
- 一篇很好的讲解SIFT算法的文章
http://blog.csdn.net/zddblog/article/details/7521424
- 关于CAShapeLayer
关于CAShapeLayer 内容大纲: CAShapeLayer简介 贝塞尔曲线与CAShapeLayer的关系 strokeStart和strokeEnd 动画 用CAShapeLayer实现进度 ...
- Java的编程逻辑--15章 并发基础
1.run()和start()的区别 2.线程的基本属性和方法 id:一个递增的整数,每创建一个线程就加一 name 优先级:从1到10,默认为5,会映射到系统中的优先级.数字越大,要优先级越高 状态 ...
- 从数据源拉取数据,将数据内容与一组搜索项做比对 go func() chanel
https://github.com/goinaction/code [root@hadoop3 sample]# go run main.go 2018/07/30 17:45:39 Registe ...
- JAVA中Stack和Heap的区别
http://m.blog.csdn.net/wl_ldy/article/details/5935528
- GSON的简单示例
https://github.com/google/gson package com.example.wolf; import com.google.gson.JsonArray; import co ...