原题:中山市选 2011 杀人游戏
方法:Tarjan
program kill_game;
const maxn=100000; maxm=300000;
type
link=^node; node=record x:longint; next:link;end;
procedure push(var x:link; const t:longint);var p:link;
begin
new(p);
p^.x:=t; p^.next:=x; x:=p;
end;
var low,dfn,pre,ss,bl:array[1..maxn]of longint;
v:array[1..maxn]of boolean;
ge:array[1..maxn]of link;
cnt,tt,k:longint;
function min(const i,j:longint):longint;
begin
if i<j then exit(i); exit(j);
end;
procedure tarjan(i:longint);
var j:longint; p:link;
begin
inc(cnt); dfn[i]:=cnt; low[i]:=cnt;
v[i]:=true; inc(tt); ss[tt]:=i;
p:=ge[i]; while p<>nil do begin
j:=p^.x;
if dfn[j]=0 then begin tarjan(j); low[i]:=min(low[i],low[j]); end else
if v[j] then low[i]:=min(low[i],dfn[j]);
p:=p^.next;
end;
if dfn[i]=low[i] then begin
inc(k); j:=i+1;
while j<>i do begin
j:=ss[tt];dec(tt);
v[j]:=false;
bl[j]:=k;
end;
end;
end;
var n,m,i,x,y,ans:longint; p:link; flag:boolean;
begin
readln(n,m); ans:=0;
for i:=1 to m do begin readln(x,y);push(ge[x],y);end;
for i:=1 to n do if dfn[i]=0 then tarjan(i);
for i:=1 to n do begin
p:=ge[i];while p<>nil do begin
if bl[i]<>bl[p^.x] then
if pre[bl[p^.x]]=0 then pre[bl[p^.x]]:=bl[i] else
if pre[bl[p^.x]]<>bl[i] then pre[bl[p^.x]]:=-1;
p:=p^.next;
end;
end;
for i:=1 to k do if pre[i]=0 then inc(ans);
for i:=1 to n do if pre[bl[i]]=0 then begin
flag:=true; p:=ge[i];
while flag and (p<>nil) do begin
if bl[i]=bl[p^.x] then flag:=false;
if pre[bl[p^.x]]<>-1 then flag:=false;
p:=p^.next;
end;
if flag then break;
end;
dec(ans,ord(flag));
writeln((n-ans)/n:0:6);
end.