[中山市选]杀人游戏 Tarjan+概率

题目描述

​ 一位冷血的杀手潜入\(Na\)-\(wiat\),并假装成平民。警察希望能在\(N\)个人里面,查出谁是杀手。警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人,谁是杀手,谁是平民。假如查证的对象是杀手,杀手将会把警察干掉。现在警察掌握了每一个人认识谁。每一个人都有可能是杀手,可看作他们是杀手的概率是相同的。

问:根据最优的情况,保证警察自身安全并知道谁是杀手的概率最大是多少?

输入输出格式

输入格式:

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

输出格式:

​ 仅包含一行一个实数,保留小数点后面 \(6\) 位,表示最大概率。

输入输出样例

输入样例#1:

5 4
1 2
1 3
1 4
1 5

输出样例#1:

0.800000

说明

​ 警察只需要查证\(1\)。假如\(1\)是杀手,警察就会被杀。假如\(1\)不是杀手,他会告诉警察\(2,3,4,5\)谁是杀手。而\(1\)是杀手的概率是\(0.2\),所以能知道谁是杀手但没被杀的概率是\(0.8\)。

题解

首先想到的是\(Tarjan\)缩点,因为缩点之后我们只需要查询环中的一个人就可以知道整个环的信息。

而且若一个环又指向另一个环,那么我们要是选择一个缩点后入度为0的点,即可以把其连通的若干个环的信息全部了解。

但是这样还有还有一些错误:

举个例子,若一共有\(N\)个人,我们查询了一些人,使得我们知道了\(N\)-\(1\)个人的身份(都是平民,否则你就挂了),那么剩下的一个人一定是杀手(排除法),那么我们就可以少去查询一个人。

所以,我们要去寻找一个大小为1且入度为0的点((缩点后)就是一个与世隔绝的人),并且他指向的点入度不为1(就是能只通过这个人来获取信息),那么我们就可以少一次询问,则标记\(flag=1\)。

综上,若\(flag==1,ans=1\)-\((缩点后入度为0的点\)-\(1)/n\).

若\(flag==0,ans=1\)-\((缩点后入度为0的点)/n\).

下面是代码欧。。。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cctype>
#define ll long long
#define R register
#define M 300005
#define N 100005
using namespace std;
template<typename T>inline void read(T &a){
char c=getchar();T x=0,f=1;
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
a=f*x;
}
int n,m,h[N],vis[N],low[N],dfn[N],num,tot,sta[N],top,cnt,col[N],siz[N];
int u[M],v[M],in[N],flag,ans;
struct node{
int nex,to;
}edge[M];
inline void add(R int u,R int v){
edge[++tot].nex=h[u];
edge[tot].to=v;
h[u]=tot;
}
inline void tarjan(R int x){
dfn[x]=low[x]=++num;
sta[++top]=x;vis[x]=1;
for(R int i=h[x];i;i=edge[i].nex){
R int xx=edge[i].to;
if(!dfn[xx]){
tarjan(xx);
low[x]=min(low[x],low[xx]);
}
else if(vis[xx])low[x]=min(low[x],dfn[xx]);
}
if(low[x]==dfn[x]){
R int now=-1;cnt++;
while(now!=x){
now=sta[top];
top--;
vis[now]=0;
siz[cnt]++;
col[now]=cnt;
}
}
}
int main(){
read(n);read(m);
for(R int i=1;i<=m;i++)
read(u[i]),read(v[i]),add(u[i],v[i]);
for(R int i=1;i<=n;i++)
if(!dfn[i])tarjan(i);
memset(h,0,sizeof(h));tot=0;
for(R int i=1;i<=m;i++)
if(col[u[i]]!=col[v[i]]){
in[col[v[i]]]++;
add(col[u[i]],col[v[i]]);//缩点后重新建图
}
for(R int i=1;i<=cnt;i++){
if(!flag&&!in[i]&&siz[i]==1){//找上述符合条件的点
R int pd=0;
for(R int j=h[i];j;j=edge[j].nex){
R int xx=edge[j].to;
if(in[xx]==1)pd=1;
}
if(!pd)flag=1;
}
if(!in[i])ans++;
}
if(flag)ans--;//若标记则可以少一次询问
printf("%.6f\n",1.0-(double)ans/(double)n);
return 0;
}

【BZOJ2438】[中山市选]杀人游戏 Tarjan+概率的更多相关文章

  1. [中山市选]杀人游戏 (Tarjan缩点)

    题目链接 Solution 可以考虑到如果知道环内一点的身份,如果凶手在其中就查出来了,同时不会有危险. 那么对警察造成威胁的就是那些身份不明且不能从其他点转移过来的点. 那么大部答案就是缩完点之后入 ...

  2. 洛谷 P4819 [中山市选]杀人游戏(tarjan缩点)

    P4819 [中山市选]杀人游戏 思路分析 题意最开始理解错了(我太菜了) 把题意简化一下,就是找到可以确定杀手身份的最小的危险查看数 (就是不知道该村名的身份,查看他的身份具有危险的查看数量),用 ...

  3. Tarjan缩点【p4819】[中山市选]杀人游戏

    Description 一位冷血的杀手潜入Na-wiat,并假装成平民.警察希望能在\(N\)个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人,谁是杀 ...

  4. [洛谷P4819][中山市选]杀人游戏

    题目大意:有一张$n$个点$m$条边的有向图,有一个关键点,如果你访问一个点,你会知道它连出的边中有没有关键点,以及若有的话是哪个.问最优策略下不访问关键点而知道关键点的概率 题解:发现若一个点不是关 ...

  5. P4819 [中山市选]杀人游戏

    题目描述 一位冷血的杀手潜入Na-wiat,并假装成平民.警察希望能在NN个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人,谁是杀手,谁是平民.假如查 ...

  6. 洛谷 P4819 [中山市选]杀人游戏

    洛谷 题目就是让我们在DAG中找到一些点,覆盖所有点. 因为是DAG,可以想到tarjan缩一下点.假设我们需要找x个点,那么答案就是(n-x)/n. 我们怎么选点呢? 敏锐的我们很快就能想到,直接选 ...

  7. 【BZOJ-2438】杀人游戏 Tarjan + 缩点 + 概率

    2438: [中山市选2011]杀人游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1638  Solved: 433[Submit][Statu ...

  8. bzoj2438: [中山市选2011]杀人游戏(强联通+特判)

    2438: [中山市选2011]杀人游戏 题目:传送门 简要题意: 给出n个点,m条有向边,进行最少的访问并且可以便利(n-1)个点,求这个方案成功的概率 题解: 一道非常好的题目! 题目要知道最大的 ...

  9. bzoj2438 杀人游戏 Tarjan强联通

    [bzoj2438][中山市选2011]杀人游戏 Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查 ...

随机推荐

  1. CKEditor 自定义按钮插入服务端图片

    CKEditor 富文本编辑器很好用,功能很强大,在加上支持服务端图片上传的CKFinder更是方便, 最近在使用CKFinder的时候发现存在很多问题,比如上传图片的时候,图片不能按时间降序排列,另 ...

  2. 11-18网页基础--第二部分CSS样式属性(1)

    第一课:样式属性 style 样式:style样式不仅可以直接在<body>中设置成整个网页的样式.格式:为了将样式.格式多样化,也可以将style单独抽出来,作为一个独立的个体,放在&l ...

  3. MyBatis总结一:快速入门

    简介 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 ...

  4. java web前端发送请求的4种方式

    表单 action, 链接href,js 绑定按钮 ajax绑定标签 <h1>通过表单提交参数</h1> <form action="/day46_v1/Ser ...

  5. 71-n皇后

    N皇后问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  6. 添加超级链接为什么用a标签

    a是anchor的简写,中文意思是锚点,而锚点的引申意思是连接,link已经被html占用了,只能用a来表示连接了.

  7. ubuntu下各种解压缩文件方式

    tar解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!)———————————————.gz解压1:gunzi ...

  8. 数据结构 merge_link合并链表

    问题描述 本题任务是维护一条非递减的链表,初始长度为 0,记这条链表为主链表.对主链表做 N 次操作,操作分两种:1 k a1 a2 … ak,表示一条长度为 k 且非递减的链表,需要将这条链表合并到 ...

  9. Linux下面的IO模型

    1. Linux下的五种I/O模型 阻塞I/O模型: 一直阻塞      应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好. 如果数据没有准备好,一直等待….数据准备好了,从内核拷贝到用户空 ...

  10. jQuery 插件开发——GridData(表格)第二版

    开发背景 表格插件之前我也写个一篇,当时写那个插件的时候,我自己还没有总结出写插件的方法,虽然功能实现了,但是使用起来还是有点别扭的,并且需要在调用写添加特定名称的方法,这个地方着实违背了开发插件的易 ...