博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
tarjin+dfs 杀人游戏
阅读量:4652 次
发布时间:2019-06-09

本文共 2908 字,大约阅读时间需要 9 分钟。

 

问题 C: [中山市选2011]杀人游戏

时间限制: 1 Sec  
内存限制: 128 MB
提交: 64  
解决: 33
[ ][ ][ ]

题目描述

一位冷血的杀手潜入 Na-wiat,并假装成平民。警察希望能在 N 个人里面,

查出谁是杀手。 
警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他
认识的人, 谁是杀手, 谁是平民。 假如查证的对象是杀手, 杀手将会把警察干掉。 
现在警察掌握了每一个人认识谁。 
每一个人都有可能是杀手,可看作他们是杀手的概率是相同的。 
问:根据最优的情况,保证警察自身安全并知道谁是杀手的概率最大是多
少?

输入

第一行有两个整数 N,M。 

接下来有 M 行,每行两个整数 x,y,表示 x 认识 y(y 不一定认识 x,例如***同志) 。

输出

仅包含一行一个实数,保留小数点后面 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。对于 100%的数据有 1≤N ≤  10 0000,0≤M ≤  30 0000

数据已加强!(→ _→ )

      其他大佬都80行,就我一百多行。

      如果一个人被审查了,那就知道了所有联系他的人身份,搜他们就是安全的,不会死。

      注意:要缩点,防止那种你认识我,我也认识你那种。。。

       更加注意:如果一个人是孤立的,就剩他一个没搜时就确定他的身份了,

        这个人要么不认识任何人,要么他认识的别人都认识。。(说白了就是不用通过他得知别人的身份)

#include
#include
#include
#include
#include
#define N 100000using namespace std;int n,m,adj[N+5],e,E;int belong[N+5],cnt,in[N+5],p=0,id[N+5],out[N+5];int zhan[N+5],head,dfn[N+5],low[N+5],hh,vis[N+5],inzhan[N+5];int A[N+5];double ans;struct node { int u,v,next;} lu[N*3+5],b[N*3+5];void add(int u,int v){ lu[++e].v=v;lu[e].u=u;lu[e].next=adj[u];adj[u]=e;}void add2(int u,int v){ b[E++].v=v;b[E].next=A[u];A[u]=E;}int check(int x){ for(int i=A[x];i;i=b[i].next) { int k=b[i].v; if(in[k]==1) return 0; } return 1;}int read(){ int sum=0,f=1;char x=getchar(); while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();} while(x>='0'&&x<='9')sum=sum*10+x-'0',x=getchar(); return sum*f;}void dfs(int x){ zhan[++head]=x;inzhan[x]=1; vis[x]=1; low[x]=dfn[x]=++hh; for(int i=adj[x];i!=-1;i=lu[i].next) { int k=lu[i].v; if(!vis[k]) { dfs(k); low[x]=min(low[x],low[k]); } else if(inzhan[k]) low[x]=min(low[x],dfn[k]); } if(dfn[x]==low[x]) { int s=0,temp; cnt++; while(1) { temp=zhan[head--]; inzhan[temp]=0; belong[temp]=cnt; s++; if(temp==x)break; } id[cnt]=s; }}int main(){ //freopen("killer.in","r",stdin); //freopen("killer.out","w",stdout); memset(adj,-1,sizeof(adj)); n=read();m=read(); int x,y; for(int i=1;i<=m;i++) { x=read();y=read(); add(x,y); } for(int i=1;i<=n;i++) if(!vis[i]) dfs(i); for(int i=1;i<=m;i++) if(belong[lu[i].u]!=belong[lu[i].v]) { in[belong[lu[i].v]]++,out[belong[lu[i].u]]++; add2(belong[lu[i].u],belong[lu[i].v]); } for(int i=1;i<=cnt;i++) if(!in[i]) ans++; for(int i=1;i<=cnt;i++) if(id[i]==1&&!in[i]&&(!out[i]||check(i))) p=1; if(p==1)ans--; ans=(double)(n-ans)/n; printf("%.6lf",ans);}

转载于:https://www.cnblogs.com/QTY2001/p/7632772.html

你可能感兴趣的文章
FactoryBean
查看>>
Coolite动态加载CheckboxGroup,无法在后台中获取
查看>>
如何在我们项目中利用开源的图表(js chart)
查看>>
nfs服务器工作原理
查看>>
C3P0连接池工具类使用
查看>>
SVN常用命令备注
查看>>
孩子教育
查看>>
解决Cacti监控图像断断续续问题
查看>>
结构体的传参理解成员的存储方式
查看>>
python 进程与线程(理论部分)
查看>>
什么是API
查看>>
Java反射中method.isBridge() 桥接方法
查看>>
[shiro学习笔记]第二节 shiro与web融合实现一个简单的授权认证
查看>>
强名称程序集(strong name assembly)——为程序集赋予强名称
查看>>
1028. List Sorting (25)
查看>>
BZOJ 1613: [Usaco2007 Jan]Running贝茜的晨练计划
查看>>
ubuntu 重启命令,ubuntu 重启网卡方法
查看>>
Linux的学习:
查看>>
JavaScript中的原型继承原理
查看>>
Python logger模块
查看>>