Description

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

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

Input

第一行有两个整数 \(N,M\)。 接下来有\(M\)行,每行两个整数 \(x,y\),表示 \(x\) 认识 \(y\)(\(y\) 不一定认识 \(x\) ,例如President同志) 。

Output

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

首先,如果一些人之间的关系存在环,那么我们可以只问其中的一个人就能知道这个环中的所有人的身份.可以降低我们的被害几率.

环?\(Tarjan\)缩点.

考虑到直接算安全的概率可能比较难算,所以我们考虑单步容斥.

安全概率=1-被杀概率

\(Tarjan\)缩点之后我们再次建图,会得到一个拓扑图.

这个拓扑图中,对于入度为\(0\)的一个点.显然,其会对被害几率有贡献.

因此我们记录图中入度为\(0\)的点的个数.

但是会存在一种情况,类似这样.

显然这个时候如果我们从左上角的点开始调查,发现没有杀手.

则杀手必定在下边的点中(这个点\(size\)必须为1,并且与其相连的点必须有其他入度).

确保自身安全的情况下,我们已经知道了杀手是谁.因此,这种点对答案并没有贡献.

且至多会有一个,

在代码中判断一下即可.

代码

#include<cstdio>
#include<cctype>
#include<iostream>
#define N 100008
#define R register
using namespace std;
inline void in(int &x)
{
int f=1;x=0;char s=getchar();
while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
while(isdigit(s)){x=x*10+s-'0';s=getchar();}
x*=f;
}
int n,m,head[N],tot,ttt,h[N],size[N],col;
struct cod{int u,v;}edge[N<<5],e[N<<2];
inline void add(int x,int y)
{
edge[++tot].u=head[x];
edge[tot].v=y;
head[x]=tot;
}
inline void ado(int x,int y)
{
e[++ttt].u=h[x];
e[ttt].v=y;
h[x]=ttt;
}
int dfn[N],low[N],top,idx,stk[N],ins[N],now,belong[N];
bool inq[N],flg;
void tarjan(int u)
{
dfn[u]=low[u]=++idx;
stk[++top]=u;inq[u]=true;
for(R int i=head[u];i;i=edge[i].u)
{
if(!dfn[edge[i].v])
{
tarjan(edge[i].v);
low[u]=min(low[u],low[edge[i].v]);
}
else if(inq[edge[i].v])
low[u]=min(low[u],dfn[edge[i].v]);
}
if(low[u]==dfn[u])
{
int now=-1;col++;
while(now!=u)
{
now=stk[top--];
size[col]++;
inq[now]=false;
belong[now]=col;
}
}
}
inline bool pd(int x)
{
for(R int i=h[x];i;i=e[i].u)
if(ins[e[i].v]==1)return false;
return true;
}
int ans;
int main()
{
in(n),in(m);
for(R int i=1,x,y;i<=m;i++)
{
in(x),in(y);
add(x,y);
}
for(R int i=1;i<=n;i++)
if(!dfn[i])tarjan(i);
for(R int x=1;x<=n;x++)
for(R int i=head[x];i;i=edge[i].u)
if(belong[edge[i].v]!=belong[x])
ins[belong[edge[i].v]]++,ado(belong[x],belong[edge[i].v]);
for(R int x=1;x<=col;x++)
{
if(!flg and size[x]==1 and !ins[x] and pd(x))flg=true;
if(!ins[x])ans++;
}
if(flg)ans--;
printf("%.6f",1-(double)((double)ans/(double)n));
}

Tarjan缩点【p4819】[中山市选]杀人游戏的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. LG4819/BZOJ2438 「中山市选2011」杀人游戏 Tarjan缩点+概率

    问题描述 LG4819 BZOJ2438 题解 发现如果有一些人之间认识关系形成环,只需要问一个人就能把控整个环. \(\mathrm{Tarjan}\)缩点. 缩点之后所有入度为\(0\)的点,必须 ...

  8. bzoj 2438: [中山市选2011]杀人游戏【tarjan】

    没看太懂题意orz 最优的是tarjan缩点之后问入度为0的点,因为问这个点可以知道整个块的情况 答案是这ans个入度为0的点都不是杀手的概率\( \frac{n-ans}{n} \) 但是有特殊情况 ...

  9. 【BZOJ-2438】杀人游戏 Tarjan + 缩点 + 概率

    2438: [中山市选2011]杀人游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1638  Solved: 433[Submit][Statu ...

随机推荐

  1. Pascal小游戏 俄罗斯方块

    俄罗斯方块已经成为了和“Hello World”一样的程序了吧? 不要直接复制,可能需要事先 Format. program cube;uses crt,graph,dos;var gd,gm:sma ...

  2. 使用java去对比2个带数学公式的字符串

    首先大家看到这个题目,可能会不屑一顾,呵呵,是的,起初我也认为这是个很简单的任务,当任务拿到手里后,经过我作为程序员来讲已经磨炼的无比通透的大脑来讲发现这其实是个坑. 故事的起因是这样的,想开发一款给 ...

  3. C语言中强制类型转换总结

    C语言中强制类型转换总结  ● 字符型变量的值实质上是一个8位的整数值,因此取值范围一般是-128-127,char型变量也可以加修饰符unsigned,则unsigned char 型变量的取值范围 ...

  4. Lua2

    1. 迭代器与Closure 在Lua中,迭代器通常为函数,每调用一次函数,即返回集合中的“下一个”元素.每个迭代器都需要在每次成功调用之间保持一些状态,这样才能知道它所在的位置和下一次遍历时的位置. ...

  5. java初学3

    1.包装类 Java提倡的万物皆对象,但是数据类型的划分出现了基本数据类型和引用数据类型,那么我们怎么能把基本数据类型称为对象呢? Java为每个原始类型提供了封装类,Integer是java为int ...

  6. Opencv3.0.0安装包

    这个资源是Opencv3.0.0安装包,包括Windows软件包,Android软件包,IOS软件包,还有opencv的源代码:需要的下载吧. 点击下载

  7. juqery基本选择器和层级选择器

    1.基本选择器,主要通过标签名称,样式,id等选择标签,如下代码是简单的使用 (1)根据标签或者样式筛选 <!DOCTYPE html> <html lang="en&qu ...

  8. CodeForces Round #515 Div.3 A. Vova and Train

    http://codeforces.com/contest/1066/problem/A Vova plans to go to the conference by train. Initially, ...

  9. 【转】Thinkphp框架的项目规划总结和踩坑经验

    http://www.360doc.com/content/16/1206/22/466494_612576533.shtml

  10. perf 的事件

    perf的事件包括: 硬件事件:branch-instrctions / branch-miss / bus-cycles / cache-miss / cache-reference / cycle ...