P4819 [中山市选]杀人游戏
题目描述
一位冷血的杀手潜入Na-wiat,并假装成平民。警察希望能在NN个人里面,查出谁是杀手。警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人,谁是杀手,谁是平民。假如查证的对象是杀手,杀手将会把警察干掉。现在警察掌握了每一个人认识谁。每一个人都有可能是杀手,可看作他们是杀手的概率是相同的。
问:根据最优的情况,保证警察自身安全并知道谁是杀手的概率最大是多少?
Solution
首先缩点, 然后需要把缩完点后的DAG上每个入度为0的点都询问一次才行.
但是有一种特殊情况是有一个入度为0的点, 它连接的点都不是必须需要它.这时就可以不询问它了.
Code
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
const int N = 1e5 + 5, M = 3e5 + 6;
class BaseGraph {
public:
struct Edge {
int v; Edge* nxt;
Edge(int _, Edge* __) : v(_), nxt(__) { }
} *head[N];
int du[N];
BaseGraph() {
memset(du, false, sizeof du);
for (int i = 1; i < N; i += 1)
head[i] = nullptr;
}
void AddEdge(int u, int v) {
du[v] += 1; head[u] = new Edge(v, head[u]);
}
};
class Graph : public BaseGraph {
int dfn[N], low[N], vis[N], que[N], col[N], siz[N];
int vis_num, col_num, top;
void Tarjan(int u) {
dfn[u] = low[u] = ++vis_num;
vis[u] = true, que[++top] = u;
for (auto edge = head[u]; edge; edge = edge->nxt) {
if (not dfn[edge->v])
Tarjan(edge->v), low[u] = std:: min(low[u], low[edge->v]);
else if (vis[edge->v])
low[u] = std:: min(low[u], low[edge->v]);
}
if (dfn[u] == low[u]) {
vis[u] = false, col[u] = ++col_num, siz[col_num] = 1;
while (que[top] != u)
vis[que[top]] = false,
col[que[top--]] = col_num, siz[col_num] += 1;
top--;
}
}
public:
double init(int n, int m) {
for (int i = 0, u, v; i < m; i += 1) {
scanf("%d%d", &u, &v);
AddEdge(u, v);
}
for (int i = 1; i <= n; i += 1)
if (not dfn[i])
Tarjan(i);
BaseGraph* rG = new BaseGraph();
for (int u = 1; u <= n; u += 1)
for (auto edge = head[u]; edge; edge = edge->nxt)
if (col[u] != col[edge->v])
rG->AddEdge(col[u], col[edge->v]);
int num_without_du = 0;
for (int i = 1; i <= col_num; i += 1)
if (not rG->du[i])
num_without_du += 1;
for (int u = 1; u <= n; u += 1)
if (not rG->du[col[u]] and siz[col[u]] == 1) {
bool flag = false;
for (auto edge = head[u]; edge; edge = edge->nxt) {
if (rG->du[col[edge->v]] == 1) {
flag = true; break;
}
}
if (not flag) {
return 1.0 - 1.0 * (num_without_du - 1) / n;
}
}
return 1.0 - 1.0 * num_without_du / n;
}
};
int main () {
int n, m;
Graph* G = new Graph();
scanf("%d%d", &n, &m);
printf("%.6f\n", G->init(n, m));
return 0;
}
P4819 [中山市选]杀人游戏的更多相关文章
- 洛谷 P4819 [中山市选]杀人游戏(tarjan缩点)
P4819 [中山市选]杀人游戏 思路分析 题意最开始理解错了(我太菜了) 把题意简化一下,就是找到可以确定杀手身份的最小的危险查看数 (就是不知道该村名的身份,查看他的身份具有危险的查看数量),用 ...
- [洛谷P4819][中山市选]杀人游戏
题目大意:有一张$n$个点$m$条边的有向图,有一个关键点,如果你访问一个点,你会知道它连出的边中有没有关键点,以及若有的话是哪个.问最优策略下不访问关键点而知道关键点的概率 题解:发现若一个点不是关 ...
- 洛谷 P4819 [中山市选]杀人游戏
洛谷 题目就是让我们在DAG中找到一些点,覆盖所有点. 因为是DAG,可以想到tarjan缩一下点.假设我们需要找x个点,那么答案就是(n-x)/n. 我们怎么选点呢? 敏锐的我们很快就能想到,直接选 ...
- 【BZOJ2438】[中山市选]杀人游戏 Tarjan+概率
[中山市选]杀人游戏 Tarjan+概率 题目描述 一位冷血的杀手潜入\(Na\)-\(wiat\),并假装成平民.警察希望能在\(N\)个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查 ...
- Tarjan缩点【p4819】[中山市选]杀人游戏
Description 一位冷血的杀手潜入Na-wiat,并假装成平民.警察希望能在\(N\)个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人,谁是杀 ...
- [中山市选]杀人游戏 (Tarjan缩点)
题目链接 Solution 可以考虑到如果知道环内一点的身份,如果凶手在其中就查出来了,同时不会有危险. 那么对警察造成威胁的就是那些身份不明且不能从其他点转移过来的点. 那么大部答案就是缩完点之后入 ...
- BZOJ_2438_[中山市选2011]杀人游戏 _强连通分量
BZOJ_2438_[中山市选2011]杀人游戏 _强连通分量 Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手.警察能够对每一个人 ...
- bzoj2438: [中山市选2011]杀人游戏(强联通+特判)
2438: [中山市选2011]杀人游戏 题目:传送门 简要题意: 给出n个点,m条有向边,进行最少的访问并且可以便利(n-1)个点,求这个方案成功的概率 题解: 一道非常好的题目! 题目要知道最大的 ...
- BZOJ2464: 中山市选[2009]小明的游戏
2464: 中山市选[2009]小明的游戏 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 280 Solved: 124[Submit][Statu ...
随机推荐
- Linux相关——画图软件安装
其实也不知道算不算Linux相关了... 装个画图软件还是很方便的,刚刚试了一下kolourpaint,感觉还行,就记录下来吧. 先记录几个快捷键emmmm print ---->全屏截图 al ...
- ocker nginx 配置反向代理和负载均衡
1. 获取及配置nginx 如果需要全站通过docker部署,那么nginx或许是不可或缺的.通过配置nginx,可以迅速实现负载均衡和反向代理服务.值得一提的是,docker官网恰好也有nginx镜 ...
- POJ3648:Wedding——题解(配2-SAT简易讲解)
http://poj.org/problem?id=3648 (在家,而且因为2-SAT写的不明不白的,所以这篇详细写) 题目大意: 有一对新人结婚,邀请了n-1 对夫妇去参加婚礼.婚礼上所有人要坐在 ...
- AOJ.863 分书问题 (DFS)
题意分析 现有n个人,n种书,给出每人对n种书的喜欢列表,求有多少种方案满足以下条件: 1.每个人都分得自己喜欢的书: 2.每个人分得书的种类各不相同,即所有种类的书均得到分配 1.采用生成测试法 生 ...
- HDOJ(HDU).2546 饭卡(DP 01背包)
HDOJ(HDU).2546 饭卡(DP 01背包) 题意分析 首先要对钱数小于5的时候特别处理,直接输出0.若钱数大于5,所有菜按价格排序,背包容量为钱数-5,对除去价格最贵的所有菜做01背包.因为 ...
- 51nod 1215 数组的宽度&poj 2796 Feel Good(单调栈)
单调栈求每个数在哪些区间是最值的经典操作. 把数一个一个丢进单调栈,弹出的时候[st[top-1]+1,i-1]这段区间就是弹出的数为最值的区间. poj2796 弹出的时候更新答案即可 #inclu ...
- JavaScript引擎是单线程的
从基础的层面来讲,理解JavaScript的定时器是如何工作的是非常重要的.计时器的执行常常和我们的直观想象不同,那是因为JavaScript引擎是单线程的.我们先来认识一下下面三个函数是如何控制计时 ...
- ioctl函数用法小记
By francis_hao Aug 27,2017 UNPV1对ioctl有算是比较详细的介绍,但是,这些request和后面的数据类型是从哪里来的,以及参数具体该如何使用呢?本文尝试在不 ...
- CentOS 6.5 下 QT4 连接 mysql 数据库的步骤
QT4 的安装请参考: CentOS 6.5 下安装 QT 4 mysql 的安装请参考: CentOS 6.5 下安装配置 mysql 1. 预防万一,先安装一下mysql-devel(一定要装!) ...
- Moodle插件开发系列——XMLDB编辑器
Moodle插件开发系列——XMLDB编辑器 位置:网站管理>开发> XML编辑器 l XML编辑器是制作install.xml文件的工具,而install.xml是指定Moodle建立 ...