1. 程式人生 > >BZOJ——2438: [中山市選2011]殺人遊戲

BZOJ——2438: [中山市選2011]殺人遊戲

+= 小數點 target esc script tchar ont 一個 中山市選

http://www.lydsy.com/JudgeOnline/problem.php?id=2438

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

殺手與村民為對立事件,警察存活概率=1-p(被殺), p(被殺)=可能為殺手的人數/n

因為警察根據最優情況選人,那麽求出scc,警察第一個人會選擇入度為零的scc,算出這些scc成為殺手的概率即可

(一個scc成為殺手的概率為 1/n ,因為在一個scc中問一個人就可以知道此塊中的所有信息)

特別的:如果存在一個獨立的scc(可以根據訪問別的人判斷此塊信息,即該塊只有一個人,連出去的點的入讀>1),

則該scc不需要統計,因為可以通過別的推斷出,即 cnt--

 1 #include <cstdio>
 2
3 #define min(a,b) (a<b?a:b) 4 5 inline void read(int &x) 6 { 7 x=0; register char ch=getchar(); 8 for(; ch>9||ch<0; ) ch=getchar(); 9 for(; ch>=0&&ch<=9; ch=getchar()) x=x*10+ch-0; 10 } 11 12 const int N(100005); 13 const int M(300005); 14 15 int n,m,sumedge,cnt; 16 int head[N],_v[M<<1],_nex[M<<1]; 17 18 inline void ins(int u,int v) 19 { 20 _v[++sumedge]=v; 21 _nex[sumedge]=head[u]; 22 head[u]=sumedge; 23 } 24 25 int tim,dfn[N],low[N],rd[N]; 26 int top,Stack[N],instack[N]; 27 int sumcol,col[N],point[N]; 28 29 void DFS(int u) 30 { 31 dfn[u]=low[u]= ++tim; 32 Stack[++top]=u; instack[u]=1; 33 for(int i=head[u]; i; i=_nex[i]) 34 { 35 if(!dfn[_v[i]]) DFS(_v[i]),low[u]=min(low[u],low[_v[i]]); 36 else if(instack[_v[i]]) low[u]=min(low[u],dfn[_v[i]]); 37 } 38 if(low[u]!=dfn[u]) return ; 39 point[col[u]= ++sumcol] ++; 40 for(; Stack[top]!=u; --top) 41 { 42 point[sumcol]++; 43 instack[Stack[top]]=0; 44 col[Stack[top]]=sumcol; 45 } 46 instack[u]=0, --top; 47 } 48 49 int Presist() 50 { 51 read(n),read(m); 52 for(int u,v,i=1; i<=m; ++i) 53 read(u),read(v),ins(u,v); 54 for(int i=1; i<=n; ++i) 55 if(!dfn[i]) DFS(i); 56 for(int u=1; u<=n; ++u) 57 for(int i=head[u]; i; i=_nex[i]) 58 if(col[u]!=col[_v[i]]) rd[col[_v[i]]]++; 59 for(int i=1; i<=sumcol; ++i) cnt+=(!rd[i]); 60 for(int u=1; u<=n; ++u) 61 { 62 if(rd[col[u]]||point[col[u]]>1) continue; 63 for(int i=head[u]; i; i=_nex[i]) 64 if(rd[col[_v[i]]]<2) goto next_; 65 cnt--; break; next_:; 66 } 67 printf("%.6lf\n",1*1.-1.*cnt/n); 68 return 0; 69 } 70 71 int Aptal=Presist(); 72 int main(int argc,char**argv){;}

BZOJ——2438: [中山市選2011]殺人遊戲