online judge:bzoj-2438,luogu-4819label:tarjan縮點,概率,yy
一位冷血的殺手潛入 na-wiat,並假裝成平民。警察希望能在 n 個人裡面,查出誰是殺手。警察能夠對每乙個人第一行有兩個整數 n,m。進行查證,假如查證的物件是平民,他會告訴警察,他認識的人, 誰是殺手, 誰是平民。 假如查證的物件是殺手, 殺手將會把警察乾掉。現在警察掌握了每乙個人認識誰。每乙個人都有可能是殺手,可看作他們是殺手的概率是相同的。問:根據最優的情況,保證警察自身安全並知道誰是殺手的概率最大是多少?
接下來有 m 行,每行兩個整數 x,y,表示 x 認識 y(y 不一定認識 x,例如hjt同志) 。——由於zz敏感裡不能放原題面233
僅包含一行乙個實數,保留小數點後面 6 位,表示最大概率。
輸入
5 4
1 2
1 3
1 4
1 5
輸出
0.800000
仔細yy一下,發現這樣乙個性質:對於乙個環,只要查證其中任何乙個人就可以知道這個環裡所有人的資訊。也就是說可以把整個環看做乙個整體,由此想到tarjan縮點,然後建立乙個強聯通分量與另乙個之間的關係(以下為了方便用"團"代替強連通分量)。
那麼最後可以得到入度為0的團的數目為ans個,設這些團構成集合s,則對與任意團∈s,只要在這個團裡任意選乙個點查證就可以知道整個團的資訊了。查證完這ans個團後,存活概率為\(1-ans/n\)(**不在我們查的那ans個人裡,我們就可以存活)。而只要存活就能找到最終的**!所以答案就是存活的概率。
但是!我們發現題目還有乙個特殊情況,比如當\(n=1,m=0\)時我們不用查也可以知道那唯一那個人是**,也就是說,當我們知道n-1人不是**後,剩下的那個肯定是**,我們不必要再冒險去查剩餘的那個人,所以得特殊處理這種情況。
我們將這種情況形象化到上面的模型中去。設該強連通分量為x,則x需滿足:
不能從別人那直接得到他的資訊——x入度為0;另外由於可能存在多個滿足上述條件的強連通分量x,而我們只能選乙個 。可以聯絡n=2,m=0的樣例進行理解,答案應該是\(0.500000\).如果x認識p,則至少還得存在乙個人認識p(不然不查證x就不能知道p)——p的入度不為1;
x這個強連通分量大小為1
**如下,主要思路就是tarjan縮點,然後特殊情況特殊處理一下。
#includeusing namespace std;
const int n=1e5+5;
stacks;
vectore[n],v[n];
int tot,cnt,n,m;
int dfn[n],low[n],in[n],sz[n],id[n];
int ing[n];
void tarjan(int x)
else if(in[y])low[x]=min(low[x],dfn[y]);
}int k;
if(low[x]==dfn[x])while(x!=k);
}}bool check(int x)
return 1;
}int main()
for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
for(int i=1;i<=n;i++)for(int j=0;jint ans=0,find=0;
for(int i=1;i<=cnt;i++)
if(find)ans--;
printf("%.6f",1.0-1.0*ans/n);
}
中山市選2011 殺人遊戲
我考試想的正解,但是.有疏漏 1.鄰接表的陣列又開小了 2.概率計算錯誤 正解就是tarjen 亂搞 1.這個圖可能是分片的圖,不一定是連通圖 2.對於其中的環進行縮點,然後在新建的圖上找indegree為0的點的數量sum,就是我們需要調查的人 稱之為張一帆 3.其中我們定義有 這樣的張一帆,它可...
中山市選2011 殺人遊戲
一位冷血的殺手潛入na wiat 並假裝成平民。警察希望能在n個人裡面查出誰是殺手 警察能夠對每乙個人進行查證,假如查證的物件是平民,他會告訴警察,他認識的人,誰是殺手,誰是平民 假如查證的物件是殺手,殺手將會把警察乾掉 現在警察掌握了每一乙個人認識誰。每一乙個人都有可能是殺手,看作他們是殺手的概率...
2438 中山市選2011 殺人遊戲
題目鏈結 題目大意 有n個人,其中乙個是殺手,可以詢問一些人,如果是殺手就會死,如果是平民,他會告訴你他認識的人中有誰是殺手有誰是平民,求自身安全並知道殺手的概率最大是多少 題解 某個人是殺手的概率相等。考慮到每個scc只問乙個點就可以,進行縮點,縮點後每個scc對答案貢獻等價。知道誰是殺手相當於知...