Codeforces 553D Nudist Beach(二分答案 + BFS)
题目链接 Nudist Beach
来源 Codeforces Round #309 (Div. 1) Problem D
题目大意:
给定一篇森林(共$n$个点),你可以在$n$个点中选择若干个构成一个集合$S$。
输入数据中会给定一些点,你不能选择这些点。
定义$S$中某城市的值:
令$A$= 该城市的在S中的邻居数量 $B$ = 该城市的所有邻居数量
那么$S$中该城市的值为$\frac{A}{B}$
定义$S$的比值为$S$中所有城市的值的最小值
题目的要求是让你确定集合$S$,使得$S$的比值最大
解题思路:
我们可以二分这个比值(在$0$到$1$之间)
然后进行check
check的时候,我们先把所有可以选择的点加入集合。
然后判断这个集合中有没有比值不符合当前check的点
如果有,删除这些不符合的点,并放入队列。
接下来在这些点的邻居中寻找有没有不符合题意的点
如果有,删除这些不符合的点,并放入队列。
就这样一直下去,直到没有点可以删除为止。
最后若集合不为空,则check函数返回true,否则返回false
时间复杂度 $O(Kn)$,$K$为二分次数
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL; const double eps = 1e-8; const int N = 100010;
int n, m, k;
vector <int> v[N];
int deg[N], irr[N], b[N], c[N], g[N], inn[N], ans[N];
int cnt = 0; bool check(double x){ int num = cnt;
queue <int> Q;
rep(i, 1, cnt) g[c[i]] = 1;
rep(i, 1, cnt) inn[c[i]] = deg[c[i]] - irr[c[i]];
rep(i, 1, cnt){
if ((double)(inn[c[i]]) / (double)deg[c[i]] < x){
Q.push(c[i]);
g[c[i]] = 0;
--num;
}
} while (!Q.empty()){
int now = Q.front(); Q.pop();
for (auto u : v[now]) if (g[u]){
--inn[u];
if ((double)inn[u] / (double)deg[u] < x){
Q.push(u);
g[u] = 0;
--num;
}
}
} if (num){
int et = 0;
rep(i, 1, cnt) if (g[c[i]]) ans[++et] = c[i];
ans[0] = num;
return true;
} else return false;
} int main(){ scanf("%d%d%d", &n, &m, &k);
rep(i, 1, k){
int x;
scanf("%d", &x);
b[x] = 1;
} rep(i, 1, m){
int x, y;
scanf("%d%d", &x, &y);
v[x].push_back(y);
v[y].push_back(x);
++deg[x], ++deg[y];
if (b[x]) ++irr[y];
if (b[y]) ++irr[x];
} double l = 0.00, r = 1.00; cnt = 0;
rep(i, 1, n) if (!b[i]) c[++cnt] = i; rep(i, 1, 100){
double mid = (l + r) / 2;
if (check(mid)) l = mid;
else r = mid - eps;
} printf("%d\n", ans[0]);
rep(i, 1, ans[0]) printf("%d ", ans[i]);
putchar(10); return 0;
}
Codeforces 553D Nudist Beach(二分答案 + BFS)的更多相关文章
- codeforces 553D . Nudist Beach 二分
题目链接 有趣的题. 给一个图, n个点m条边. 有k个点不可选择. 现在让你选出一个非空的点集, 使得点集中strength最小的点的strength最大. strength的定义:一个点周围的点中 ...
- Codeforces 553D Nudist Beach(图论,贪心)
Solution: 假设已经选了所有的点. 如果从中删掉一个点,那么其它所有点的分值只可能减少或者不变. 如果要使若干步删除后最小的分值变大,那么删掉的点集中肯定要包含当前分值最小的点. 所以每次删掉 ...
- [Codeforces 1199C]MP3(离散化+二分答案)
[Codeforces 1199C]MP3(离散化+二分答案) 题面 给出一个长度为n的序列\(a_i\)和常数I,定义一次操作[l,r]可以把序列中<l的数全部变成l,>r的数全部变成r ...
- {POJ}{3897}{Maze Stretching}{二分答案+BFS}
题意:给定迷宫,可以更改高度比,问如何使最短路等于输入数据. 思路:由于是单调的,可以用二分答案,然后BFS验证.这里用优先队列,每次压入也要进行检查(dis大小)防止数据过多,A*也可以.好久不写图 ...
- Codeforces 772A Voltage Keepsake - 二分答案
You have n devices that you want to use simultaneously. The i-th device uses ai units of power per s ...
- 2018.12.08 codeforces 939E. Maximize!(二分答案)
传送门 二分答案好题. 题意简述:要求支持动态在一个数列队尾加入一个新的数(保证数列单增),查询所有子数列的 最大值减平均值 的最大值. 然而网上一堆高人是用三分做的. 我们先考虑当前的答案有可能由什 ...
- Educational Codeforces Round 21 Problem F (Codeforces 808F) - 最小割 - 二分答案
Digital collectible card games have become very popular recently. So Vova decided to try one of thes ...
- [USACO2003][poj2110]Mountain Walking(二分答案+bfs)
http://poj.org/problem?id=2110 题意:给你一个n*n矩形(n<=100),每个位置上都有一个数字代表此处山的高度,要从(1,1)走到 (n,n),要求一条路径使得这 ...
- CH Round #72树洞[二分答案 DFS&&BFS]
树洞 CH Round #72 - NOIP夏季划水赛 描述 在一片栖息地上有N棵树,每棵树下住着一只兔子,有M条路径连接这些树.更特殊地是,只有一棵树有3条或更多的路径与它相连,其它的树只有1条或2 ...
随机推荐
- phpExcel使用方法一
include 'PHPExcel.php'; include 'PHPExcel/Writer/Excel2007.php'; //或者include 'PHPExcel/Writer/Excel5 ...
- windows server2008R2 64位 配置 mysql-8.0.15-winx64
下载mysql: 1 https://dev.mysql.com/downloads/mysql/ 如图: 然后在解压的文件夹里面新建 my.ini文件,内容如下 按 Ctrl+C 复制代码 按 Ct ...
- Lecture 1
Principles of GIS( UNSW Metternicht ) outline:data input---data management---data manipulation+data ...
- apply 与 lambda
Python中的lambda和apply用法 https://blog.csdn.net/anshuai_aw1/article/details/82347016
- ZOJ 2314 (sgu 194) Reactor Cooling (无源汇有上下界最大流)
题意: 给定n个点和m条边, 每条边有流量上下限[b,c], 求是否存在一种流动方法使得每条边流量在范围内, 而且每个点的流入 = 流出 分析: 无源汇有上下界最大流模板, 记录每个点流的 in 和 ...
- 迷宫问题&MakeFile
先看一个有意思的问题, 我们定义一个二维数组表示迷宫. 它表示一个迷宫, 其中的1表示墙壁,0表示可以走的路, 只能横着走或竖着走,不能斜着走, 我们要编程序找出从左上角到右下角的路线.其实这个问题可 ...
- Scala学习-02-方法
算数和操作符重载 所有的操作符都是方法. a + b 是一种缩写形式 : a .+ b “+”是方法名(操作符重载) ++和—— Scala中并没有“++”和“——”.需要使用“+=”和“-=” ...
- python 学习分享-文件操作篇
文件操作 f_open=open('*.txt','r')#以只读的方式(r)打开*.txt文件(需要与py文件在同一目录下,如果不同目录,需写全路径) f_open.close()#关闭文件 打开文 ...
- 使用xmake检测编译器特性支持
如果我们要写跨平台的c/c++代码,很多时候需要处理由于不同编译器对c/c++各个标准支持力度不同导致的兼容性问题,一般通常的解决办法是:自己在代码中通过宏去判断各个编译器的版本.内置宏.标准库宏._ ...
- Goal Oriented Action Planning for a Smarter AI
Goal Oriented Action Planning for a Smarter AI by Brent Owens23 Apr 2014 Goal Oriented Action Planni ...