[bzoj 2438][中山市选2011]杀人游戏 概率+tarjan
考试的时候想了很多,不知道它那个概率究竟是怎么算。。没想到能蒙30分。rp爆发hhh
题解转自不知道哪里来的老师发的(代码出自自己)。
实际上警察就是两种结果——查到犯人或死亡,而死亡事件一定是包含在“调查未知身份的人”,也就是说调查未知身份的人越多,死亡概率就越高,所以我们要求的问题就是警察要尽可能少调查未知身份的人
给出公式 P(死亡)=调查的未知身份的人数/总人数
“死亡”和”存活”是对立事件,而”存活”等价于”找到犯人” 所以 ans=1−P死亡 问题转化为求调查最少的未知身份人的人数
同时我们发现,对于一个环(1认识2,2认识3,3认识1),我们是可以把他们看作一个人的,也就是说,只要调查了他们其中一个,其他两个我们一定可以安全到达(知道他是犯人或平民) 对于这个问题,我们使用tarjan对图进行缩点处理,然后我们所要调查的对象就是重构图中那些入度为0的点(没有人知道这些点里的人的身份),调查的未知身份的人数就是这些点的数量 (如果其中入度不为0,那么我们一定可以从一个入度为0的点走到这里,即我们调查这个点时是知道这里面的人的身份的)
注意:
有一个特殊情况,如果说至少有一个点,它只有一个人,他是完全孤立的(即没有人知道这个人的身份,他对外面的世界也一无所知)或者他认识的每个人都被除他以外的其他人所认识(即它所能到达的点的入度>1),那么我们在安全调查完除他以外的其他人后,他一定是杀手(但在图上他属于未知身份的人),我们不必去调查他,直接抓起来就可以了,所以调查未知身份的人数要– 1(我们可以想得简单些,比如n=1时这个人一定是杀手,即P存活=1)
#include<cstdio> #include<cstring> #include<iostream> using namespace std; #define pos(i,a,b) for(int i=(a);i<=(b);i++) #define N 500000 int n,m; int low[N],dfn[N],stack[N],instack[N],belong[N]; int peo[N]; struct haha{ int next,to; }; haha edgechu[N],edge[N]; int head[N],cnt=1,cntchu=1,headchu[N]; void add(int u,int v){ edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt++; } void addchu(int u,int v){ edgechu[cntchu].to=v; edgechu[cntchu].next=headchu[u]; headchu[u]=cntchu++; } int ji=1,hea,cn=1; void tarjan(int now){ low[now]=dfn[now]=ji++; stack[++hea]=now; instack[now]=1; for(int i=headchu[now];i;i=edgechu[i].next){ int to=edgechu[i].to; if(dfn[to]==-1){ tarjan(to); low[now]=min(low[now],low[to]); } else{ if(instack[to]){ low[now]=min(low[now],dfn[to]); } } } if(low[now]==dfn[now]){ int temp; while(1){ temp=stack[hea--]; belong[temp]=cn; instack[temp]=0; peo[cn]++; if(temp==now) break; } cn++; } } int in[N],out[N]; int ans; int flag[N]; int main(){ freopen("killer.in","r",stdin); freopen("killer.out","w",stdout); scanf("%d%d",&n,&m); memset(dfn,-1,sizeof(dfn)); pos(i,1,m){ int x,y; scanf("%d%d",&x,&y); addchu(x,y); } pos(i,1,n){ if(dfn[i]==-1) tarjan(i); } cn--; pos(i,1,n){ for(int v=headchu[i];v;v=edgechu[v].next){ int j=edgechu[v].to; if(belong[i]!=belong[j]){ add(belong[i],belong[j]); in[belong[j]]++; out[belong[i]]++; } } } pos(i,1,cn){ if(in[i]==0){ ans++; } } pos(i,1,cn){ if(peo[i]==1){ if(in[i]==0&&out[i]==0){ ans--; double temp=(double)(n-ans)/n; printf("%0.6lf",temp); return 0; } else{ for(int j=head[i];j;j=edge[j].next){ int to=edge[j].to; if(in[to]>1){ flag[i]++; } } if(flag[i]==out[i]&&(flag[i])){ ans--; double temp=(double)(n-ans)/n; printf("%0.6lf",temp); return 0; } } } } double temp=(double)(n-ans)/n; printf("%0.6lf",temp); return 0; }
[bzoj 2438][中山市选2011]杀人游戏 概率+tarjan的更多相关文章
- bzoj 2438: [中山市选2011]杀人游戏【tarjan】
没看太懂题意orz 最优的是tarjan缩点之后问入度为0的点,因为问这个点可以知道整个块的情况 答案是这ans个入度为0的点都不是杀手的概率\( \frac{n-ans}{n} \) 但是有特殊情况 ...
- bzoj 2438 [中山市选2011]杀人游戏(SCC+概率)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2438 [题意] N个人中有一个杀手,每次询问一个人可能被杀或被告知其认识的人中谁是杀手 ...
- BZOJ——2438: [中山市选2011]杀人游戏
http://www.lydsy.com/JudgeOnline/problem.php?id=2438 Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个 ...
- BZOJ 2438: [中山市选2011]杀人游戏
Description 给你一个有向图,求至少询问多少次能够得到全部点的信息. Sol Tarjan + 强连通分量缩点 + 判断. 先缩点,如果我们知道了强连通分量里的任意一个点,我们就可以知道这些 ...
- [BZOJ 2438] [中山市选2011]杀人游戏 Tarjan缩点
这个题很容易想到正解就是缩点找入度为零的点,那么我们考虑一种特殊情况就是,一个入度为零的点我们不访问他就知道他是不是凶手,那么这样的话就是:I. 他是一个真·孤立的点 II. 他在图里但是在他的强联通 ...
- BZOJ 2438 [中山市选2011]杀人游戏 ——期望DP
发现每一次死亡的几率相等,所以只需要判断最少问多少人即可. 并且环上的点任意询问都可以. 所以直接Tarjan缩点,然后计算入度为0的点的数目. 但是还有一些情况的时候会减少一次询问,比如说:$1-& ...
- bzoj2438: [中山市选2011]杀人游戏(强联通+特判)
2438: [中山市选2011]杀人游戏 题目:传送门 简要题意: 给出n个点,m条有向边,进行最少的访问并且可以便利(n-1)个点,求这个方案成功的概率 题解: 一道非常好的题目! 题目要知道最大的 ...
- BZOJ_2438_[中山市选2011]杀人游戏 _强连通分量
BZOJ_2438_[中山市选2011]杀人游戏 _强连通分量 Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手.警察能够对每一个人 ...
- bzoj2438[中山市选2011]杀人游戏
Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面, 查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他 认识的人, ...
随机推荐
- Vue.js 介绍入门
Vue.js 的目标 是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件.Vue.js 是一个用于创建 Web 交互界面的库.它让你通过简单而灵活的 API 创建由数据驱动的 UI 组件. ...
- zookeeper client API实现(python kazoo 的实现)
这里主要分析zookeeper client API的实现方式,以python kazoo的实现代码为蓝本进行逻辑分析. 一.代码框架及介绍 API分为同步模式和异步模式.同步模式是在异步模式的基础上 ...
- JavaScript从入门到忘记
JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处理. 一.如何编写 二.变 ...
- win7-x64安装mysql5.7.11(官方zip版)
1.下载官方安装包(http://www.mysql.com/downloads/),此zip包是没有安装器的(*.msi),也没有辅助配置的自动程序. 2.解压zip包,将文件放入指定目录,如:D: ...
- My sql添加远程用户root密码为password
添加远程用户root密码为password grant all privileges on *.* to root@localhost identified by '123321' with gran ...
- java操作DBF的使用
1.引入javadbf.4.1.jar 2. import com.linuxense.javadbf.DBFField; import com.linuxense.javadbf.DBFRead ...
- CISCO2960配置vlan
一.VTP配置 1.VLAN database 2.(VLAN)#vtp domain wx 3.(VLAN)#vtp server 二.VLAN配置 1.VLAN database 2.(VLAN) ...
- CentOS 6.8重新安装yum
问题来源:我在虚拟机上安装vncserver,输入yum install tigervnc tigervnc-server出现问题,所以就重新安装了一遍yum. 具体的过程看如下这个链接:http:/ ...
- Carbondata源码系列(一)文件生成过程
在滴滴的两年一直在加班,人也变懒了,就很少再写博客了,最近在进行Carbondata和hive集成方面的工作,于是乎需要对Carbondata进行深入的研究. 于是新开一个系列,记录自己学习Carbo ...
- 输入3个数a,b,c,按大小顺序输出
题目:输入3个数a,b,c,按大小顺序输出 package com.li.FiftyAlgorthm; import java.util.Scanner; /** * 题目:输入3个数a,b,c,按大 ...