题目描述

一位冷血的杀手潜入Na-wiat,并假装成平民。警察希望能在NN个人里面,查出谁是杀手。警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人,谁是杀手,谁是平民。假如查证的对象是杀手,杀手将会把警察干掉。现在警察掌握了每一个人认识谁。每一个人都有可能是杀手,可看作他们是杀手的概率是相同的。

问:根据最优的情况,保证警察自身安全并知道谁是杀手的概率最大是多少?

Solution

首先缩点, 然后需要把缩完点后的DAG上每个入度为0的点都询问一次才行.

但是有一种特殊情况是有一个入度为0的点, 它连接的点都不是必须需要它.这时就可以不询问它了.

Code

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <iostream>
  4. #include <algorithm>
  5. const int N = 1e5 + 5, M = 3e5 + 6;
  6. class BaseGraph {
  7. public:
  8. struct Edge {
  9. int v; Edge* nxt;
  10. Edge(int _, Edge* __) : v(_), nxt(__) { }
  11. } *head[N];
  12. int du[N];
  13. BaseGraph() {
  14. memset(du, false, sizeof du);
  15. for (int i = 1; i < N; i += 1)
  16. head[i] = nullptr;
  17. }
  18. void AddEdge(int u, int v) {
  19. du[v] += 1; head[u] = new Edge(v, head[u]);
  20. }
  21. };
  22. class Graph : public BaseGraph {
  23. int dfn[N], low[N], vis[N], que[N], col[N], siz[N];
  24. int vis_num, col_num, top;
  25. void Tarjan(int u) {
  26. dfn[u] = low[u] = ++vis_num;
  27. vis[u] = true, que[++top] = u;
  28. for (auto edge = head[u]; edge; edge = edge->nxt) {
  29. if (not dfn[edge->v])
  30. Tarjan(edge->v), low[u] = std:: min(low[u], low[edge->v]);
  31. else if (vis[edge->v])
  32. low[u] = std:: min(low[u], low[edge->v]);
  33. }
  34. if (dfn[u] == low[u]) {
  35. vis[u] = false, col[u] = ++col_num, siz[col_num] = 1;
  36. while (que[top] != u)
  37. vis[que[top]] = false,
  38. col[que[top--]] = col_num, siz[col_num] += 1;
  39. top--;
  40. }
  41. }
  42. public:
  43. double init(int n, int m) {
  44. for (int i = 0, u, v; i < m; i += 1) {
  45. scanf("%d%d", &u, &v);
  46. AddEdge(u, v);
  47. }
  48. for (int i = 1; i <= n; i += 1)
  49. if (not dfn[i])
  50. Tarjan(i);
  51. BaseGraph* rG = new BaseGraph();
  52. for (int u = 1; u <= n; u += 1)
  53. for (auto edge = head[u]; edge; edge = edge->nxt)
  54. if (col[u] != col[edge->v])
  55. rG->AddEdge(col[u], col[edge->v]);
  56. int num_without_du = 0;
  57. for (int i = 1; i <= col_num; i += 1)
  58. if (not rG->du[i])
  59. num_without_du += 1;
  60. for (int u = 1; u <= n; u += 1)
  61. if (not rG->du[col[u]] and siz[col[u]] == 1) {
  62. bool flag = false;
  63. for (auto edge = head[u]; edge; edge = edge->nxt) {
  64. if (rG->du[col[edge->v]] == 1) {
  65. flag = true; break;
  66. }
  67. }
  68. if (not flag) {
  69. return 1.0 - 1.0 * (num_without_du - 1) / n;
  70. }
  71. }
  72. return 1.0 - 1.0 * num_without_du / n;
  73. }
  74. };
  75. int main () {
  76. int n, m;
  77. Graph* G = new Graph();
  78. scanf("%d%d", &n, &m);
  79. printf("%.6f\n", G->init(n, m));
  80. return 0;
  81. }

P4819 [中山市选]杀人游戏的更多相关文章

  1. 洛谷 P4819 [中山市选]杀人游戏(tarjan缩点)

    P4819 [中山市选]杀人游戏 思路分析 题意最开始理解错了(我太菜了) 把题意简化一下,就是找到可以确定杀手身份的最小的危险查看数 (就是不知道该村名的身份,查看他的身份具有危险的查看数量),用 ...

  2. [洛谷P4819][中山市选]杀人游戏

    题目大意:有一张$n$个点$m$条边的有向图,有一个关键点,如果你访问一个点,你会知道它连出的边中有没有关键点,以及若有的话是哪个.问最优策略下不访问关键点而知道关键点的概率 题解:发现若一个点不是关 ...

  3. 洛谷 P4819 [中山市选]杀人游戏

    洛谷 题目就是让我们在DAG中找到一些点,覆盖所有点. 因为是DAG,可以想到tarjan缩一下点.假设我们需要找x个点,那么答案就是(n-x)/n. 我们怎么选点呢? 敏锐的我们很快就能想到,直接选 ...

  4. 【BZOJ2438】[中山市选]杀人游戏 Tarjan+概率

    [中山市选]杀人游戏 Tarjan+概率 题目描述 ​ 一位冷血的杀手潜入\(Na\)-\(wiat\),并假装成平民.警察希望能在\(N\)个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查 ...

  5. Tarjan缩点【p4819】[中山市选]杀人游戏

    Description 一位冷血的杀手潜入Na-wiat,并假装成平民.警察希望能在\(N\)个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人,谁是杀 ...

  6. [中山市选]杀人游戏 (Tarjan缩点)

    题目链接 Solution 可以考虑到如果知道环内一点的身份,如果凶手在其中就查出来了,同时不会有危险. 那么对警察造成威胁的就是那些身份不明且不能从其他点转移过来的点. 那么大部答案就是缩完点之后入 ...

  7. BZOJ_2438_[中山市选2011]杀人游戏 _强连通分量

    BZOJ_2438_[中山市选2011]杀人游戏 _强连通分量 Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手.警察能够对每一个人 ...

  8. bzoj2438: [中山市选2011]杀人游戏(强联通+特判)

    2438: [中山市选2011]杀人游戏 题目:传送门 简要题意: 给出n个点,m条有向边,进行最少的访问并且可以便利(n-1)个点,求这个方案成功的概率 题解: 一道非常好的题目! 题目要知道最大的 ...

  9. BZOJ2464: 中山市选[2009]小明的游戏

    2464: 中山市选[2009]小明的游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 280  Solved: 124[Submit][Statu ...

随机推荐

  1. [TJOI2013]最长上升子序列 平衡树

    其实是一道性质题. 首先观察到插入的数是递增的, 那么根据上升子序列的性质, 我们的非法情况就是统计到了在一个数前面的后插入的数, 但是由于插入的数是递增的,显然插入这个数后,这个数就是最大的,所以除 ...

  2. BZOJ4004:[JLOI2015]装备购买——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4004 https://www.luogu.org/problemnew/show/P3265 脸哥 ...

  3. [bzoj] 3673 3674 可持久化并查集 || 可持久化数组

    原题 加强版 题意: 可持久化并查集模板-- 题解: 用可持久化线段树维护一个可持久化数组,来记录每一次操作后的状态. 不能用路径压缩,但是要按置合并,使复杂度保证在O(log) #include&l ...

  4. Numpy模块(数值计算)

    Numpy是高性能科学计算和数据分析的基础包.它是pandas等其他各种工具的基础. NumPy的主要功能: ndarray,一个多维数组结构,高效且节省空间 无需循环对整组数据进行快速运算的数学函数 ...

  5. annot refer to a non-final variable * inside an inner class defined in a different method"错误解析

    在使用Java局部内部类或者匿名内部类时,若该类调用了所在方法的局部变量,则该局部变量必须使用final关键字来修饰,否则将会出现编译错误“Cannot refer to a non-final va ...

  6. 可能是国内最火的开源项目 —— C/C++ 篇

    程序员们,在北上广你还能买房吗? >>>   推荐阅读: 可能是最火的开源项目 -- Java 篇 可能是国内最火的开源项目 -- PHP 篇 可能是国内最火的开源项目 -- Pyt ...

  7. MyBatis框架的使用及源码分析(七) MapperProxy,MapperProxyFactory

    从上文<MyBatis框架中Mapper映射配置的使用及原理解析(六) MapperRegistry> 中我们知道DefaultSqlSession的getMapper方法,最后是通过Ma ...

  8. js高阶函数--判断数据类型、函数胡柯里化;

    一.判断数据类型: 常见的判断有typeof.instanceof. constructor. prototype,先来看typeof: var a = "hello world" ...

  9. [hdu2460]network(依次连边并询问图中割边数量) tarjan边双联通分量+lca

    题意: 给定一个n个点m条边的无向图,q个操作,每个操作给(x,y)连边并询问此时图中的割边有多少条.(连上的边会一直存在) n<=1e5,m<=2*10^5,q<=1e3,多组数据 ...

  10. 【BZOJ4903】【CTSC2017】吉夫特 [DP]

    吉夫特 Time Limit: 15 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description Input 第一行一个整数n. 接下 ...