殺人遊戲 Tarjan縮點

2022-03-19 19:12:29 字數 1503 閱讀 7672

​ 一位冷血的殺手潛入na-wiat,並假裝成平民。警察希望能在n個人裡面,查出誰是殺手。警察能夠對每乙個人進行查證,假如查證的物件是平民,他會告訴警察,他認識的人,誰是殺手,誰是平民。假如查證的物件是殺手,殺手將會把警察乾掉。現在警察掌握了每乙個人認識誰。每乙個人都有可能是殺手,可看作他們是殺手的概率是相同的。

問:根據最優的情況,保證警察自身安全並知道誰是殺手的概率最大是多少?

輸入格式:

​ 第一行有兩個整數n,m。 接下來有m行,每行兩個整數x,y,表示x認識yy不一定認識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,那麼我們至少需要新增...