杀人游戏
Description
一位冷血的杀手潜入 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
Sample Output
0.800000
HINT
警察只需要查证 1。假如1是杀手,警察就会被杀。假如 1不是杀手,他会告诉警
察 2,3,4,5 谁是杀手。而 1 是杀手的概率是 0.2,所以能知道谁是杀手但没被杀的概
率是0.8。对于 100%的数据有 1≤N ≤ 10 0000,0≤M ≤ 30 0000

数据已加强!
Source

分析:

要想知道谁是凶手,必须要知道所有人的情况才行。

显然问的人越少警察越安全

如果一个人被询问,则他所连通的所有点都可知道,(理由很简单,一个人被问到,它认识的人中谁是好人也知道了,对于好人,我们可以放心大胆的问,这样联通的点信息全部知道了)

这样,本题转化为在一个有向图中,选出x个点使得从该这些点出发能遍历到所有点,要求x最小。

先tarjan缩点,然后统计入度为0的scc即可(一个scc与一个点等效,有凶手概率都是1/n)

这样就结束了吗,不是。这种看法存在漏洞,比如说三个人ABC,A认知B,在这种情况下,我只需要询问A(于是AB都知道了),然后推理出C即可。

所以我们要进行判断,如果存在一个点它入度出度为0,或入度为0,自己所连的点都有两个以上的入度(这样自己的后继可被其它点遍历而自己可被推理出来),则将x-1,注意只能进行一次。

输出(n-x)/n,保留6位小数即可。

注意:在一个scc有多边连同一点只算一次,每个scc只统计一次。

代码:

program play;
type
point=^node;
node=record
x:longint; next:point;
end;
var
a:array[..]of point;
f,low,dfn,q,w:array[..]of longint;
g,instack:array[..]of boolean;
n,i,m,s,t,num,x,y,ans:longint;
function min(x,y:longint):longint;
begin
if x<y then min:=x else min:=y;
end;
procedure add(x,y:longint);
var p:point;
begin
new(p); p^.x:=y; p^.next:=a[x]; a[x]:=p;
end;
procedure tarjan(x:longint);
var y:longint; p:point;
begin
inc(s); low[x]:=s; dfn[x]:=s; inc(t); q[t]:=x;
instack[x]:=true;
new(p); p:=a[x];
while p<>nil do
begin
y:=p^.x;
if dfn[y]= then begin tarjan(y); low[x]:=min(low[x],low[y]); end
else if instack[y]=true then low[x]:=min(low[x],dfn[y]);
p:=p^.next;
end;
if dfn[x]=low[x] then
begin
inc(num);
repeat
y:=q[t]; dec(t); f[y]:=x;instack[y]:=false;
until x=y;
end;
end;
procedure scc;
var x,y:longint; p:point;
begin
fillchar(g,sizeof(g),false);
for x:= to n do
begin
new(p); p:=a[x];
while p<>nil do
begin
y:=p^.x; g[f[y]]:=false; p:=p^.next;
end;
new(p); p:=a[x];
while p<>nil do
begin
y:=p^.x;
if (g[f[y]]=false)and(f[x]<>f[y]) then
begin g[f[y]]:=true; inc(w[f[y]]); end;
p:=p^.next;
end;
end;
end;
function cheak(x:longint):boolean;
var p:point; y:longint;
begin
if w[x]<> then exit(false);
new(p); p:=a[x];
while p<>nil do
begin
y:=p^.x;
if (f[x]=f[y])or(w[y]<=) then exit(false);
p:=p^.next;
end;
exit(true);
end;
begin
assign(input,'play.in');
reset(input);
assign(output,'play.out');
rewrite(output);
readln(n,m);
for i:= to m do
begin
readln(x,y); add(x,y);
end;
for i:= to n do begin dfn[i]:=; low[i]:=; w[i]:=; instack[i]:=false; end;
s:=; t:=; num:=;
for i:= to n do if dfn[i]= then tarjan(i);
scc;
for i:= to n do g[i]:=false;
for i:= to n do
if (w[f[i]]=)and(g[f[i]]=false) then begin inc(ans); g[f[i]]:=true; end;
for i:= to n do if cheak(f[i])=true then begin dec(ans); break; end;
writeln((n-ans)/n::);
close(input); close(output);
end.

BZOJ 2438:杀人游戏(tarjan+概率)的更多相关文章

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

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

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

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

  3. bzoj2438 杀人游戏 Tarjan强联通

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

  4. [BZOJ 2438] [中山市选2011]杀人游戏 Tarjan缩点

    这个题很容易想到正解就是缩点找入度为零的点,那么我们考虑一种特殊情况就是,一个入度为零的点我们不访问他就知道他是不是凶手,那么这样的话就是:I. 他是一个真·孤立的点 II. 他在图里但是在他的强联通 ...

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

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

  6. 【BZOJ2438】 [中山市选2011]杀人游戏 tarjan强连通分量+缩点

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

  7. 【bzoj2438】[中山市选2011]杀人游戏 Tarjan

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

  8. BZOJ2438: [中山市选2011]杀人游戏(tarjan)

    题意 题目链接 Sol 这题挺考验阅读理解能力的.. 如果能读懂的话,不难发现这就是在统计有多少入度为\(0\)的点 缩点后判断一下即可 当然有一种例外情况是\(1 -> 3, 2 -> ...

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

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

随机推荐

  1. 使用nsis开发自定义安装包使用心得,以及遇到坑

    因为新公司需要开发pc应用的自定义安装包,开始时候计划使用nsis开发,论坛上面有很多不错的例子,而且完成度很强, 随便拿来修改使用,但是后续的开发过程中遇到的问题就逐个出现. 首先说一下nsis的优 ...

  2. 常见的HTTP状态码有哪些?

    当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求.当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求. ...

  3. Hibernate进阶学习4

    Hibernate进阶学习4 深入学习hibernate的查询语句 测试HQL查询 package com.hibernate.test; import com.hibernate.domain.Cu ...

  4. 7-3 python操作excel

    1.写excel 写入特定单元格数据 # .导入xlwt模块 # .新建一个excel # .添加一个sheet页 # .往指定的单元格中写入数据 # .保存excel import xlwt boo ...

  5. python——标准异常总结

    请参考此网站: Python 标准异常总结 https://fishc.com.cn/forum.php?mod=viewthread&tid=45814&extra=page%3D1 ...

  6. Mybatis中updateByPrimaryKeySelective和updateByPrimaryKey区别

    int updateByPrimaryKeySelective(TbItem record); int updateByPrimaryKey(TbItem record); 上面的是逆转工程生成的Ma ...

  7. js过滤和包含数组方法

    let data=[{'Linda':'apple'},{'Linda':'pear'},{'Linda':'apricot'},{'Linda':'peach'},{'Linda':'grape'} ...

  8. 笔记-python-调试

    笔记-python-调试 一般在pycharm下调试或使用log查看输出日志,有时小程序不想这么麻烦,也有一些方便使用的调试方式可以使用. 1.      idle调试 1.打开Python shel ...

  9. [bzoj1552][Cerc2007]robotic sort&&[bzoj3506][Cqoi2014]排序机械臂

    非常垃圾的一道平衡树,结果被日了一天.很难受嗷嗷嗷 首先不得不说网上的题解让我这个本来就不熟悉平衡树的彩笔很难受——并不好理解. 还好Sinogi大佬非常的神,一眼就切掉了,而且用更加美妙的解法. 题 ...

  10. ZOJ 3329 Problem Set (期望dp)

    One Person Game There is a very simple and interesting one-person game. You have 3 dice, namely Die1 ...