日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[补档][中山市选2011]杀人游戏

發布時間:2025/4/14 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [补档][中山市选2011]杀人游戏 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

[中山市選2011]殺人游戲

題目

一位冷血的殺手潛入 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

OUTPUT

0.800000

解題報告

考試時沒想出來,隨便打的輸出樣例- - 正解: 警察只有兩種結果——查到犯人或者死,而死一定是包含在“調查未知身份的人”,也就是說調查未知身份的人越多,死亡概率越高,所以我們要求警察如何盡可能少調查未知身份的人 那么問題就很簡單了,我們發現對于一個強連通分量,我們可以把他們看作一個人,因為調查了其中一個,剩余的都可以安全到達(正確性顯然,因為你只要安全調查了其中的一個人,你就可以通過每次確認安全的人從而調查整個強連通分量),那么我們就可以tarjan一下,那么我們調查的對象就為縮點后入度為0的點(因為你無法從其他點通向這個點,你只能通過調查其中一個未知身份的人來調查整個強連通分量,如果警察RP不好,第一個選中殺手,警察就GG了),所以調查的未知身份的人數就是這些點的數量。 坑點: 存在這樣一種情況,至少有一個點,且只有一個人,而且沒人認識他,他也不認識別人,或者他認識的每個人都能被除他以外的其他人所認識(即入度>1),那么我們調查完其他人后,他就是殺手(正確性顯然,對于第一種情況,考慮n=1就行,對于第二種情況,他認識的人已經被調查過了,而其他人自然也被調查過,那么他自己就是剩下未調查的唯一可能的殺手)。 那么如何處理呢? 進行特判,順便dfs一下,判斷是否屬于這種情況就可以啦 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 inline int read(){ 6 int sum(0); 7 char ch(getchar()); 8 for(;ch<'0'||ch>'9';ch=getchar()); 9 for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar()); 10 return sum; 11 } 12 struct edge{ 13 int s,e,n; 14 }a[300001],b[100001]; 15 int pre[100001],tot; 16 int adj[100001],ttt; 17 inline void insert(int s,int e){ 18 a[++tot].s=s; 19 a[tot].e=e; 20 a[tot].n=pre[s]; 21 pre[s]=tot; 22 } 23 inline void add(int s,int e){ 24 b[++ttt].s=s; 25 b[ttt].e=e; 26 b[ttt].n=adj[s]; 27 adj[s]=ttt; 28 } 29 int n,m; 30 int stack[100001],top; 31 int cnt,low[100001],dfn[100001],bl[100001],qlt; 32 bool vis[100001]; 33 int size[100001]; 34 inline int my_min(int a,int b){ 35 return a<b?a:b; 36 } 37 inline void tarjan(int u){ 38 cnt++; 39 vis[u]=1; 40 low[u]=dfn[u]=cnt; 41 stack[++top]=u; 42 for(int i=pre[u];i!=-1;i=a[i].n){ 43 int e(a[i].e); 44 if(!dfn[e]){ 45 tarjan(e); 46 low[u]=my_min(low[u],low[e]); 47 } 48 else 49 if(vis[e]) 50 low[u]=my_min(low[u],dfn[e]); 51 } 52 if(low[u]==dfn[u]){ 53 int tmp; 54 qlt++; 55 while(1){ 56 tmp=stack[top--]; 57 bl[tmp]=qlt; 58 vis[tmp]=0; 59 if(tmp==u) 60 break; 61 } 62 } 63 } 64 bool flag[100001]; 65 inline void uni(int u){//坑點處理dfs 66 for(int i=adj[u];i!=-1;i=b[i].n){ 67 int e(b[i].e); 68 if(!vis[e]){ 69 vis[e]=1; 70 uni(e); 71 size[u]+=size[e]; 72 } 73 } 74 } 75 int ans(0); 76 int ind[100001]; 77 int main(){ 78 // freopen("killer.in","r",stdin); 79 // freopen("killer.out","w",stdout); 80 memset(pre,-1,sizeof(pre)); 81 memset(adj,-1,sizeof(adj)); 82 n=read(),m=read(); 83 for(int i=1;i<=m;i++){ 84 int x(read()),y(read()); 85 insert(x,y); 86 } 87 for(int i=1;i<=n;i++) 88 if(!dfn[i]) 89 tarjan(i); 90 for(int i=1;i<=n;i++) 91 size[bl[i]]++; 92 for(int i=1;i<=m;i++){ 93 int s(a[i].s),e(a[i].e); 94 if(bl[s]!=bl[e]) 95 add(bl[s],bl[e]),ind[bl[e]]++; 96 } 97 for(int i=1;i<=qlt;i++) 98 if(!ind[i]){//坑點特判 99 uni(i); 100 if(size[i]==1){ 101 ans=-1; 102 break; 103 } 104 } 105 for(int i=1;i<=qlt;i++) 106 if(ind[i]==0) 107 ans++; 108 printf("%.6lf",(double)(n-ans)/(double)n); 109 } View Code 哀民生之多艱啊- -

轉載于:https://www.cnblogs.com/hzoi-mafia/p/7276887.html

總結

以上是生活随笔為你收集整理的[补档][中山市选2011]杀人游戏的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。