杀人游戏
Time Limits: 1000 ms Memory Limits: 512000 KB Detailed Limits
Description
一位冷血的杀手潜入Na-wiat,并假装成平民。警察希望能在N个人里面,查出谁是杀手。
警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人,谁是杀手,谁是平民。假如查证的对象是杀手,杀手将会把警察干掉。
现在警察掌握了每一个人认识谁。
每一个人都有可能是杀手,可看作他们是杀手的概率是相同的。
问:根据最优的情况,保证警察自身安全并知道谁是杀手的概率最大是多少?
Input
输入文件killer.in,第一行有两个整数N,M。
接下来有M行,每行两个整数x,y,表示x认识y(y不一定认识x,例如胡锦涛同志)。
Output
输出文件killer.out仅包含一行一个实数,保留小数点后面6位,表示最大概率。
Sample Input
5 4
1 2
1 3
1 4
1 5
Sample Output
0.800000
Data Constraint
Hint
【样例解释】
警察只需要查证1。假如1是杀手,警察就会被杀。假如1不是杀手,他会告诉警察2,3,4,5谁是杀手。而1是杀手的概率是0.2,所以能知道谁是杀手但没被杀的概率是0.8。
【数据规模】
对于30%的数据有1≤N ≤ 10,0≤M ≤10
对于100%的数据有1≤N ≤ 10 0000,0≤M ≤ 30 0000.
题解:对于每一个点,期望被杀概率为1/n,答案为1-num/n,num为选取的点数
要使选取的点数
const
maxn=100000;
maxm=300000;
inf='investigation10.in';
var
last,next,last1,next1:array[0..maxm]of longint;
e,e1:array[0..maxm,1..2]of longint;
n,m,scc,sum,sum1:longint;
v,ju:array[1..maxn]of boolean;
dfn,low,belong:array[1..maxn]of longint;
du,stack:array[0..maxn]of longint;
i,j,flag,ans,cou,pp,top:longint;
procedure add(x,y:longint);
begin
inc(sum);
e[sum,1]:=x;e[sum,2]:=y;
next[sum]:=last[x];
last[x]:=sum;
end;
procedure add1(x,y:longint);
begin
inc(sum1);
e1[sum1,1]:=x;e1[sum1,2]:=y;
next1[sum1]:=last[x];
last1[x]:=sum1;
end;
procedure init;
var
i,x,y:longint;
begin
readln(n,m);
for i:=1 to m do
begin
readln(x,y);
add(x,y);
end;
end;
function min(a,b:longint):longint;
begin
if a<b then exit(a) else exit(b);
end;
procedure tarjan(x:longint);
var
i,go:longint;
begin
inc(cou);
dfn[x]:=cou;low[x]:=cou;
v[x]:=true;
inc(top);
stack[top]:=x;
i:=last[x];
while i<>0 do
begin
go:=e[i,2];
if dfn[go]=0 then
begin
tarjan(go);
low[x]:=min(low[x],low[go]);
end
else
if v[go] then
begin
low[x]:=min(low[x],dfn[go]);
end;
i:=next[i];
end;
if dfn[x]=low[x] then
begin
v[x]:=false;
inc(scc);
belong[x]:=scc;
if stack[top]=x then ju[scc]:=true;
while stack[top]<>x do
begin
belong[stack[top]]:=scc;
v[stack[top]]:=false;
dec(top);
end;
dec(top);
end;
end;
procedure build;
var
i,kk:longint;
begin
for i:=1 to m do
begin
if belong[e[i,1]]<>belong[e[i,2]] then
begin
inc(du[belong[e[i,2]]]);
add1(belong[e[i,1]],belong[e[i,2]]);
end;
end;
end;
begin
// assign(input,inf);reset(input);
//assign(output,ouf);rewrite(Output);
init;
for i:=1 to n do
begin
if dfn[i]<>0 then continue;
cou:=1;
tarjan(i);
end;
build;
for i:=1 to scc do
if du[i]=0 then
begin
inc(ans);
if flag=1 then continue;
if ju[i] then
begin
j:=last[i];
flag:=1;
while j<>0 do
begin
if du[e1[j,2]]<=1 then
begin
flag:=0;
break;
end;
j:=next[j];
end;
end;
end;
writeln((1-(ans-flag)/n):0:6);
//close(input);
end.