一位冷血的殺手潛入na-wiat,並假裝成平民。警察希望能在n
個人裡面,查出誰是殺手。警察能夠對每乙個人進行查證,假如查證的物件是平民,他會告訴警察,他認識的人,誰是殺手,誰是平民。假如查證的物件是殺手,殺手將會把警察乾掉。現在警察掌握了每乙個人認識誰。每乙個人都有可能是殺手,可看作他們是殺手的概率是相同的。
問:根據最優的情況,保證警察自身安全並知道誰是殺手的概率最大是多少?
輸入格式:
第一行有兩個整數n
,m
。 接下來有m
行,每行兩個整數x
,y
,表示x
認識y
(y
不一定認識x
,例如president同志) 。
輸出格式:
僅包含一行乙個實數,保留小數點後面6
位,表示最大概率。
輸入樣例:
5 4
1 2
1 3
1 4
1 5
輸出樣例:
0.800000
警察只需要查證1。假如1是殺手,警察就會被殺。假如1不是殺手,他會告訴警察2,3,4,5誰是殺手。而1是殺手的概率是0.2,所以能知道誰是殺手但沒被殺的概率是0.8。
#include#include#include#includeconst int m = 3e5+10,n = 1e5+10;
int head[n],dfn[n],low[n],belong[n],sta[n],siz[n],ru[n],x[m],y[m],dfs_clock,scc_cnt,top;
using namespace std;
struct edgee[m];
int len;
void addedge(int u,int v)
void tarjan(int u)
else if(!belong[v])low[u]=min(low[u],dfn[v]);
} if(dfn[u]==low[u]) }}
int main()
for(int i = 1;i <= n;i++)
for(int i = 1;i <= m;i++)
} int ans = 0,flag = 0; //flag判斷是否是殺手
for(int i = 1;i <= scc_cnt;i++)
if(!pd)flag = 1; //是殺手
} if(!ru[i])ans++; //不是殺手且無法通過其他強連通分量到達的點,需要詢問一次
} if(flag)ans--; //通過排除法少了一次訪問次數
printf("%.6f\n",1.0-(double)ans/(double)n);//每次訪問都可能直接訪問到**,ans/n為警察有危險的概率
return 0;
}
bzoj 2438 殺人遊戲(tarjan縮點)
根據題意只要找出有多少個不連通的集合就可以了。但是在判定的時候有環的話會有點麻煩,所以先縮點,在dfs。但是如果有乙個點它的所有連的點不止它乙個入度的話 而且這個點的入度為0,那麼最後剩它的時候就不用問了。include include include includeusing namespace ...
Tarjan縮點 SPFA 縮點
洛谷p3387縮點 tarjan spfa求dag上單源最短路模板題 用tarjan在原圖上求scc 縮點 用縮點之後的scc建乙個有向無環圖 scc權為此scc內所有點點權和 在新建的dag上將scc權視為邊權跑spfa 求scc 1 到scc n 的最長路即為所求答案 include inclu...
Tarjan演算法 縮點
我們這一篇是在已經了解tarjan演算法的基礎之上開始寫的,如果不了解的話,請先看大牛們 關於tarjan演算法的部落格。首先我們對於乙個有向無環的圖 dag 至少新增幾條邊才能使它變為強連通圖?我們很容易根據有向無環圖的性質得到,我們計算入度為零的點數為a,出度為零的點數為b,那麼我們至少需要新增...