BZOJ 2438:杀人游戏(tarjan+概率)
杀人游戏
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+概率)的更多相关文章
- 【BZOJ2438】[中山市选]杀人游戏 Tarjan+概率
[中山市选]杀人游戏 Tarjan+概率 题目描述 一位冷血的杀手潜入\(Na\)-\(wiat\),并假装成平民.警察希望能在\(N\)个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查 ...
- 【BZOJ-2438】杀人游戏 Tarjan + 缩点 + 概率
2438: [中山市选2011]杀人游戏 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1638 Solved: 433[Submit][Statu ...
- bzoj2438 杀人游戏 Tarjan强联通
[bzoj2438][中山市选2011]杀人游戏 Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查 ...
- [BZOJ 2438] [中山市选2011]杀人游戏 Tarjan缩点
这个题很容易想到正解就是缩点找入度为零的点,那么我们考虑一种特殊情况就是,一个入度为零的点我们不访问他就知道他是不是凶手,那么这样的话就是:I. 他是一个真·孤立的点 II. 他在图里但是在他的强联通 ...
- LG4819/BZOJ2438 「中山市选2011」杀人游戏 Tarjan缩点+概率
问题描述 LG4819 BZOJ2438 题解 发现如果有一些人之间认识关系形成环,只需要问一个人就能把控整个环. \(\mathrm{Tarjan}\)缩点. 缩点之后所有入度为\(0\)的点,必须 ...
- 【BZOJ2438】 [中山市选2011]杀人游戏 tarjan强连通分量+缩点
Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是 ...
- 【bzoj2438】[中山市选2011]杀人游戏 Tarjan
题目描述 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是杀手, 谁是平民 ...
- BZOJ2438: [中山市选2011]杀人游戏(tarjan)
题意 题目链接 Sol 这题挺考验阅读理解能力的.. 如果能读懂的话,不难发现这就是在统计有多少入度为\(0\)的点 缩点后判断一下即可 当然有一种例外情况是\(1 -> 3, 2 -> ...
- [中山市选]杀人游戏 (Tarjan缩点)
题目链接 Solution 可以考虑到如果知道环内一点的身份,如果凶手在其中就查出来了,同时不会有危险. 那么对警察造成威胁的就是那些身份不明且不能从其他点转移过来的点. 那么大部答案就是缩完点之后入 ...
随机推荐
- Oracle SCN与时间的相互转换
1.SCN转换成时间 select scn_to_timestamp(current_scn) from v$database; 2.时间转换成SCN select timestamp_to_scn( ...
- linux系统中 redis 保存数据的5种形式 linux后端模式启动 jedis无法通过IP地址和端口号访问如何修改linux防火墙
vim修改redis.conf配置文件(我的已经复制到虚拟机的/usr/local/redis/bin目录下)为daemonize yes, 以后端模式启动 ./redis-server redis. ...
- javaWeb基础 javascript bom5个对象
bom 也称为浏览器对象 browser object model(浏览器对象模型),由五个对象组成: Window:浏览器窗口 最顶层对象. Navigator :浏览器对 ...
- BZOJ3884: 上帝与集合的正确用法(欧拉函数 扩展欧拉定理)
Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 3860 Solved: 1751[Submit][Status][Discuss] Descripti ...
- 什么是shell 是不是什么时候都可以使用shell
因为Shell似乎是各UNIX系统之间通用的功能,并且经过了POSIX的标准化.因此,Shell脚本只要"用心写"一次,即可应用到很多系统上.因此,之所以要使用Shell脚本是基于 ...
- #Python编程从入门到实践#第四章笔记
#Python编程从入门到实践#第四章笔记 操作列表 1.遍历列表 使用for循环,遍历values列表 for value in values: print(value) 2.数字列表 使 ...
- 笔记-HTTP及HTTPS
笔记-HTTP及HTTPS 1. HTTP 1.1. 简介 HTTP:hyper text transfer protocol 超文本传输协议 http常用请求方式,method ge ...
- 关于学习less后一些感悟
学习了一天的less发现,自己被自己弄的晕头转向,好在是学明白了! 一.写自己的第一个less css样式编程: 网址:http://www.1024i.com/demo/less/document. ...
- Android快速发布项目到jcenter详解
不管别人的教程多详细,都有他们忽略的坑,所以,都要自己动手.我也是参考了许多许多的博客,弄了一上午加下午十分钟,才搞定. 参考: 下面这个是大部分的步骤 http://blog.csdn.net/zh ...
- ListView.getChildCount() 详解
ListView.getCount() 返回的所包含的item总个数 ListView.getChildCount() (ViewGroup.getChildCount()) 返回的是现实层面上所包含 ...