題目描述
一位冷血的殺手潛入na-wiat,並假裝成平民。警察希望能在
n n
個人裡面,查出誰是殺手。警察能夠對每乙個人進行查證,假如查證的物件是平民,他會告訴警察,他認識的人,誰是殺手,誰是平民。假如查證的物件是殺手,殺手將會把警察乾掉。現在警察掌握了每乙個人認識誰。每乙個人都有可能是殺手,可看作他們是殺手的概率是相同的。
問:根據最優的情況,保證警察自身安全並知道誰是殺手的概率最大是多少?
輸入輸出格式
輸入格式:
第一行有兩個整數 n,
m' role="presentation" style="position: relative;">n,m
n,m。 接下來有
m m
行,每行兩個整數 x,
y' role="presentation" style="position: relative;">x,y
x,y,表示
x x
認識 y' role="presentation" style="position: relative;">yy(
y y
不一定認識
x' role="presentation" style="position: relative;">x
x,例如president同志) 。
注:原文zz敏感內容已替換
輸出格式:
僅包含一行乙個實數,保留小數點後面
6 6
位,表示最大概率。
輸入輸出樣例
輸入樣例#1:
5 4
1 2
1 3
1 4
1 5
輸出樣例#1:
0.800000
說明警察只需要查證
1' role="presentation" style="position: relative;">1
1。假如
1 1
是殺手,警察就會被殺。假如
1' role="presentation" style="position: relative;">1
1不是殺手,他會告訴警察 2,
3,4,
5 2,3
,4,5
誰是殺手。而
1 1
是殺手的概率是
0.2' role="presentation" style="position: relative;">0.2
0.2,所以能知道誰是殺手但沒被殺的概率是
0.8 0.8
。對於100
% 100
%的資料有 1≤
n≤100000,0
≤m≤300000
1 ≤n
≤100000,0
≤m
≤300000
分析:
假如我們調查了乙個人,有1n
1
n概率被殺,有kn
k
n概率調查到**,
k k
表示與當前人認識的人數。剩下的就是知道這個人以及他認識的人都不是**的概率,而下次調查人數變少,概率變大,但是要乘上當前觸發這個條件的概率,所以其實都是1n
' role="presentation" style="position: relative;">1n1
n。顯然我們調查一次沒有找到**,下次調查一定調查那些已經被知道不是**的人,也就是說,我們調查乙個人,可以知道他間接認識的人的身份。
因為原圖是有向圖,我們可以先縮點,顯然乙個聯通分量只需要調查乙個人。那麼答案是入度為
0 0
的點的個數。
但是這有例外,比如說,如果全部人
n' role="presentation" style="position: relative;">n
n個不認識,我們只需要調查n−
1 n−1
個人即可,並不是所有人,可以理解為有乙個入度為
0 0
的點的情況在調查了其他的點後,不需要調查就知道了。
也就是說,如果縮點後的圖存在乙個點,他的入度為
0' role="presentation" style="position: relative;">0
0,而且這個聯通分量縮點前也是乙個點而不是乙個環,並且與他認識的點入度都大於
1 1
(也就是可以通過其他人調查,不調查這個點不影響),那麼總調查數就可以減
1' role="presentation" style="position: relative;">1
1,但是只能允許不調查乙個這樣的點。答案就是1−
numn
1 −n
um
n,nu
m num
為總調查數。
**:
#include
#include
#include
#include
const
int maxn=1e5+7;
const
int maxe=3e5+7;
using
namespace
std;
int flag,n,m,num,x,y,cnt,bcnt;
int r[maxn],dfn[maxn],low[maxn],belong[maxn],d[maxn],ls[maxn],vis[maxn];
vector
sta;
struct edgeg[maxe];
void dfs(int x)
else
}if (low[x]==dfn[x])
}}int main()
for (int i=1;i<=n;i++)
num=0;
for (int i=1;i<=m;i++)
for (int i=1;i<=bcnt;i++)
for (int i=1;i<=n;i++)
}if (!rec)}}
double ans=1-(double)(num-flag)/(double)n;
printf("%.6lf",ans);
}
P4819 中山市選 殺人遊戲
這題想必大家很容易想到圖論建模。每個人都是乙個結點,與他認識的人連一條邊,每過乙個點我們就能這樣擴充套件下去。我們需要使 殺的概率小,簡單貪心 盡量去找認識人多的人詢問,即找到聯通較多邊的那個結點詢問。我們可以求出途中所有的強連通分量,用tarjan演算法縮點,然後找出所有入讀為0的點。但這題有乙個...
P4819 中山市選 殺人遊戲
一位冷血的殺手潛入na wiat,並假裝成平民。警察希望能在nn個人裡面,查出誰是殺手。警察能夠對每乙個人進行查證,假如查證的物件是平民,他會告訴警察,他認識的人,誰是殺手,誰是平民。假如查證的物件是殺手,殺手將會把警察乾掉。現在警察掌握了每乙個人認識誰。每乙個人都有可能是殺手,可看作他們是殺手的概...
P4819 中山市選 Tarjan SCC
題意 傳送門 p4819 中山市選 殺人遊戲 題解若 x xx 認識 y yy,則從 x xx 向 y yy 連一條有向邊,得到一張有向圖。觀察發現,若存在環,那麼任取環上一點即可,則有 1 n 1 n1 n 的概率是殺手 否則,可獲取下乙個節點的身份,直到環上最後乙個節點或發現殺手。那麼使用 ta...