一位冷血的杀手潜入 Na-wiat,并假装成平民。
警察希望能在 N 个人里面,查出谁是杀手。
警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是杀手, 谁是平民。
假如查证的对象是杀手, 杀手将会把警察干掉。
现在警察掌握了每一个人认识谁。
每一个人都有可能是杀手,可看作他们是杀手的概率是相同的。
问:根据最优的情况,保证警察自身安全并知道谁是杀手的概率最大是多少?
第一行有两个整数 N,M。
接下来有 M 行,每行两个整数 x,y,表示 x 认识 y(y 不一定认识 x,例如19260817等等。。。) 。
仅包含一行一个实数,保留小数点后面 6 位,表示最大概率。
警察只需要查证 1。
假如1是杀手,警察就会被杀。
假如 1不是杀手,他会告诉警察 2,3,4,5 谁是杀手。
而 1 是杀手的概率是 0.2,所以能知道谁是杀手但没被杀的概率是0.8。
对于 100%的数据有 1≤N ≤ 10 0000,0≤M ≤ 30 0000
数据已加强!
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #define MAXN 100010 using namespace std; int n,m,c=1,ans=0; int head[MAXN],colour[MAXN],num[MAXN],indegree[MAXN]; struct Edge{ int x,y; }edge[MAXN*3]; struct Graph{ int next,to; }a[MAXN*3]; inline int read(){ int date=0,w=1;char c=0; while(c<‘0‘||c>‘9‘){if(c==‘-‘)w=-1;c=getchar();} while(c>=‘0‘&&c<=‘9‘){date=date*10+c-‘0‘;c=getchar();} return date*w; } namespace Tarjan{ int d=1,top=1,s=0; int cstack[MAXN],deep[MAXN],low[MAXN]; bool vis[MAXN]; inline void add(int x,int y){ a[c].to=y;a[c].next=head[x];head[x]=c++; } void dfs(int x){ deep[x]=low[x]=d++; vis[x]=true; cstack[top++]=x; for(int i=head[x];i;i=a[i].next){ int v=a[i].to; if(!deep[v]){ dfs(v); low[x]=min(low[x],low[v]); } else if(vis[v])low[x]=min(low[x],deep[v]); } if(low[x]==deep[x]){ s++; do{ colour[cstack[top-1]]=s; vis[cstack[top-1]]=false; }while(cstack[--top]!=x); } } void clean(){ c=1; memset(head,0,sizeof(head)); memset(a,0,sizeof(a)); } void solve(){ int x,y; for(int i=1;i<=m;i++){ edge[i].x=read();edge[i].y=read(); add(edge[i].x,edge[i].y); } for(int i=1;i<=n;i++)if(!deep[i])dfs(i); for(int i=1;i<=n;i++)num[colour[i]]++; clean(); for(int i=1;i<=m;i++){ x=edge[i].x;y=edge[i].y; if(colour[x]!=colour[y]){ indegree[colour[y]]++; add(colour[x],colour[y]); } } } } void work(){ bool flag=false; for(int i=1;i<=Tarjan::s;i++){ if(!flag&&!indegree[i]&&num[i]==1){ bool f=false; for(int j=head[i];j;j=a[j].next){ int v=a[j].to; if(indegree[v]==1)f=true; } if(!f)flag=true; } if(!indegree[i])ans++; } if(flag)ans--; printf("%.6lf\n",1.00-1.00*ans/n); } void init(){ n=read();m=read(); Tarjan::solve(); } int main(){ init(); work(); return 0; }
原文:https://www.cnblogs.com/Yangrui-Blog/p/9924528.html