[补档][中山市选2011]杀人游戏

题目

一位冷血的杀手潜入 Na-wiat,并假装成平民。警察希望能在 N 个人里面,查出谁是杀手。

警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人,谁是杀手,谁是平民。假如查证的对象是杀手,杀手将会把警察干掉。

现在警察掌握了每一个人认识谁。

每一个人都有可能是杀手,可看作他们是杀手的概率是相同的。

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

INPUT

第一行有两个整数 N,M。

接下来有 M 行,每行两个整数 x,y,表示 x 认识 y(y 不一定认识 x)。

OUTPUT

仅包含一行一个实数,保留小数点后面 6 位,表示最大概率。

SAMPLE

INPUT

5 4

1 2

1 3

1 4

1 5

OUTPUT

0.800000

解题报告

考试时没想出来,随便打的输出样例- -

正解:

警察只有两种结果——查到犯人或者死,而死一定是包含在“调查未知身份的人”,也就是说调查未知身份的人越多,死亡概率越高,所以我们要求警察如何尽可能少调查未知身份的人

那么问题就很简单了,我们发现对于一个强连通分量,我们可以把他们看作一个人,因为调查了其中一个,剩余的都可以安全到达(正确性显然,因为你只要安全调查了其中的一个人,你就可以通过每次确认安全的人从而调查整个强连通分量),那么我们就可以tarjan一下,那么我们调查的对象就为缩点后入度为0的点(因为你无法从其他点通向这个点,你只能通过调查其中一个未知身份的人来调查整个强连通分量,如果警察RP不好,第一个选中杀手,警察就GG了),所以调查的未知身份的人数就是这些点的数量。

坑点:

存在这样一种情况,至少有一个点,且只有一个人,而且没人认识他,他也不认识别人,或者他认识的每个人都能被除他以外的其他人所认识(即入度>1),那么我们调查完其他人后,他就是杀手(正确性显然,对于第一种情况,考虑n=1就行,对于第二种情况,他认识的人已经被调查过了,而其他人自然也被调查过,那么他自己就是剩下未调查的唯一可能的杀手)。

那么如何处理呢?

进行特判,顺便dfs一下,判断是否属于这种情况就可以啦

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 using namespace std;
  5 inline int read(){
  6     int sum(0);
  7     char ch(getchar());
  8     for(;ch<‘0‘||ch>‘9‘;ch=getchar());
  9     for(;ch>=‘0‘&&ch<=‘9‘;sum=sum*10+(ch^48),ch=getchar());
 10     return sum;
 11 }
 12 struct edge{
 13     int s,e,n;
 14 }a[300001],b[100001];
 15 int pre[100001],tot;
 16 int adj[100001],ttt;
 17 inline void insert(int s,int e){
 18     a[++tot].s=s;
 19     a[tot].e=e;
 20     a[tot].n=pre[s];
 21     pre[s]=tot;
 22 }
 23 inline void add(int s,int e){
 24     b[++ttt].s=s;
 25     b[ttt].e=e;
 26     b[ttt].n=adj[s];
 27     adj[s]=ttt;
 28 }
 29 int n,m;
 30 int stack[100001],top;
 31 int cnt,low[100001],dfn[100001],bl[100001],qlt;
 32 bool vis[100001];
 33 int size[100001];
 34 inline int my_min(int a,int b){
 35     return a<b?a:b;
 36 }
 37 inline void tarjan(int u){
 38     cnt++;
 39     vis[u]=1;
 40     low[u]=dfn[u]=cnt;
 41     stack[++top]=u;
 42     for(int i=pre[u];i!=-1;i=a[i].n){
 43         int e(a[i].e);
 44         if(!dfn[e]){
 45             tarjan(e);
 46             low[u]=my_min(low[u],low[e]);
 47         }
 48         else
 49             if(vis[e])
 50                 low[u]=my_min(low[u],dfn[e]);
 51     }
 52     if(low[u]==dfn[u]){
 53         int tmp;
 54         qlt++;
 55         while(1){
 56             tmp=stack[top--];
 57             bl[tmp]=qlt;
 58             vis[tmp]=0;
 59             if(tmp==u)
 60                 break;
 61         }
 62     }
 63 }
 64 bool flag[100001];
 65 inline void uni(int u){//坑点处理dfs
 66     for(int i=adj[u];i!=-1;i=b[i].n){
 67         int e(b[i].e);
 68         if(!vis[e]){
 69             vis[e]=1;
 70             uni(e);
 71             size[u]+=size[e];
 72         }
 73     }
 74 }
 75 int ans(0);
 76 int ind[100001];
 77 int main(){
 78 //  freopen("killer.in","r",stdin);
 79 //  freopen("killer.out","w",stdout);
 80     memset(pre,-1,sizeof(pre));
 81     memset(adj,-1,sizeof(adj));
 82     n=read(),m=read();
 83     for(int i=1;i<=m;i++){
 84         int x(read()),y(read());
 85         insert(x,y);
 86     }
 87     for(int i=1;i<=n;i++)
 88         if(!dfn[i])
 89             tarjan(i);
 90     for(int i=1;i<=n;i++)
 91         size[bl[i]]++;
 92     for(int i=1;i<=m;i++){
 93         int s(a[i].s),e(a[i].e);
 94         if(bl[s]!=bl[e])
 95             add(bl[s],bl[e]),ind[bl[e]]++;
 96     }
 97     for(int i=1;i<=qlt;i++)
 98         if(!ind[i]){//坑点特判
 99             uni(i);
100             if(size[i]==1){
101                 ans=-1;
102                 break;
103             }
104         }
105     for(int i=1;i<=qlt;i++)
106         if(ind[i]==0)
107             ans++;
108     printf("%.6lf",(double)(n-ans)/(double)n);
109 }

哀民生之多艰啊- -

时间: 2024-08-04 15:52:35

[补档][中山市选2011]杀人游戏的相关文章

[中山市选2011]杀人游戏

[中山市选2011]杀人游戏 时间限制: 1 Sec  内存限制: 128 MB提交: 64  解决: 33[提交][状态][讨论版] 题目描述 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是杀手, 谁是平民. 假如查证的对象是杀手, 杀手将会把警察干掉. 现在警察掌握了每一个人认识谁. 每一个人都有可能是杀手,可看作他们是杀手的概率是相同的. 问:根据最优的情况,保

【BZOJ2438】[中山市选2011]杀人游戏 Tarjan

[BZOJ2438][中山市选2011]杀人游戏 Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是杀手, 谁是平民. 假如查证的对象是杀手, 杀手将会把警察干掉. 现在警察掌握了每一个人认识谁. 每一个人都有可能是杀手,可看作他们是杀手的概率是相同的. 问:根据最优的情况,保证警察自身安全并知道谁是杀手的概率最大是多少? Input 第一行有两个

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

2438: [中山市选2011]杀人游戏 题目:传送门 简要题意: 给出n个点,m条有向边,进行最少的访问并且可以便利(n-1)个点,求这个方案成功的概率 题解: 一道非常好的题目! 题目要知道最大的存活概率,那么也就是找到直接找到杀手的最小概率 那么我们采用强联通缩点: 统计每个联通分量的入度,如果入度为0(证明除此联通分量里的点,没有人可以知道连通分量里的信息,那就一定要先选一个人访问),那么sum++(因为依据题意,假如问到连通分量里的任意一个人,只要ta不是杀手,那么一定可以安全的遍历强

BZOJ 2438: [中山市选2011]杀人游戏

Description 给你一个有向图,求至少询问多少次能够得到全部点的信息. Sol Tarjan + 强连通分量缩点 + 判断. 先缩点,如果我们知道了强连通分量里的任意一个点,我们就可以知道这些点的信息,和这些点所连接的其他点的信息,显然我们需要知道的就是缩点后入度为0的点. 然后还有最后一个入度为0的单点,并且他的所有儿子都能被其他节点访问,那么最后就可以直接推断出这个点,所以要删去. Code #include<cstdio> #include<stack> #inclu

bzoj 2438 [中山市选2011]杀人游戏(SCC+概率)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2438 [题意] N个人中有一个杀手,每次询问一个人可能被杀或被告知其认识的人中谁是杀手谁是平民,问不被杀的情况下知道谁是杀手的概率. [思路] 对于一个scc,如果我们询问一个不是杀手的人,就可以成功遍历整个scc. 求scc,然后缩点. 对于每一个入度为0的scc,我们需要去询问一下,那么被杀的概率为1/n * ans.ans为入度为0的scc个数. 但还有一种特殊的情况,如果一个

BZOJ 2438 中山市选 2011 杀人游戏 Tarjan

题目大意:给出一张有向人物关系图,告诉你谁认识谁,认识具有传递性.其中有一个人是犯人.现在警察要调查谁是犯人.他可以问任何人.但是如果他问到了犯人,那么它就会死.如果他问到的一个人认识犯人,这个人就会告诉警察谁是犯人.问警察保证自身安全并知道犯人是谁的概率最大是多少. 思路:这个题前一阵子重测了,加强了数据,卡掉了网上一片AC代码.. 正解并不是很难想.首先先缩点,整个图变成拓扑图,之后会出现一些类似根的东西,这些scc入度为0,只要警察询问了这些scc每一个中的任意一个,就肯定能知道谁是犯人.

BZOJ 2438 中山市选2011 杀人游戏 Tarjan

题目大意:有n个人,其中一个是杀手,可以询问一些人,如果是杀手就会死,如果是平民,他会告诉你他认识的人中有谁是杀手有谁是平民 警告:数据有误,请谨慎提交! 易知如果我需要访问x个人,那么答案就是1-x/n 我们需要访问最少的人 如果我访问的人是平民,那么这个点所有的后继我都能知道 于是Tarjan缩点之后入度为零的点就是答案 但是还有一个问题 比如说这组样例 3 1 1 2 我访问了1,那么1和2是不是凶手我就都知道了 既然只有三个人,我知道1和2是不是凶手,那么3也一定知道 没必要去访问3 于

bzoj 2438: [中山市选2011]杀人游戏 (强联通分量 Tarjan)

Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是杀手, 谁是平民. 假如查证的对象是杀手, 杀手将会把警察干掉. 现在警察掌握了每一个人认识谁. 每一个人都有可能是杀手,可看作他们是杀手的概率是相同的. 问:根据最优的情况,保证警察自身安全并知道谁是杀手的概率最大是多少? Input 第一行有两个整数 N,M. 接下来有 M 行,每行两个整数 x

BZOJ——2438: [中山市选2011]杀人游戏

http://www.lydsy.com/JudgeOnline/problem.php?id=2438 Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手.警察能够对每一个人 进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是杀手, 谁是平民. 假如查证的对象是杀 手, 杀手将会把警察干掉.现在警察掌握了每一个人认识谁.每一个人都有可能是杀手,可看作他们是杀手的概 率是相同的.问:根据最优的情况,保证警察自身安全并知