Description

一位冷血的杀手潜入 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

Sample Output

0.800000

HINT

警察只需要查证 1。假如1是杀手,警察就会被杀。假如 1不是杀手,他会告诉警



察 2,3,4,5 谁是杀手。而 1 是杀手的概率是 0.2,所以能知道谁是杀手但没被杀的概



率是0.8。对于 100%的数据有 1≤N ≤  10 0000,0≤M ≤  30 0000

数据已加强!

思路:本人初中党表示对概率这东西不是很懂。。。

大神的题解:http://www.cnblogs.com/xkui/p/4552391.html

题目的关键在于要想到,既然是关系问题(思考一下并查集是否可以解?不能,我认为出现了“x 认识 y(y 不一定认识 x,例如胡锦涛同志)”表明不可用),就涉及到只要是几个人构成了有向图强联通分量,那么质问其中一人就可以得知所有的分量内的关系,缩一下点就没有必要枚举所有人。而此时,直接去问那些入度为0的分量。至于为什么可以参照这个公式哦:

ans=(n-1)/n(第一次问不是罪犯)*[(s1-1/n-1)(集合在第一点集中)+((n-s1)/(n-1))*((n-s1-1)/(n-s1))*((s2-1)*(n-s1-1))(分别为,不在第一点集,第二次不问到罪犯,在第二点集的概率)+...]。(问入度为0的点集可以保证它们之间互补相干)。

当然此题程序也并非单纯的模板

特判:当有一个分量只包括一个点、入度为0且不影响其他分量的入度是否为0(似乎不是桥),那么当其他点问过后,就不用关心这个点了,从ans中删除它的增量1。

1590224

  ksq2013 2438 Accepted 37256 kb 1032 ms C++/Edit 2083 B 2016-08-14 11:08:14
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,m,first[1000111],du[1000111],sz[1000111],hd[1000111],ecnt,ans=0;
int pre[1000111],sccn[1000111],lowlink[1000111],mstack[1000111],stack_cnt,dfs_clock,scc_cnt;
struct edge{
int u,v,nxt;
}e[300333];
void link(int u,int v)
{
e[++ecnt].u=u;
e[ecnt].v=v;
e[ecnt].nxt=first[u];
first[u]=ecnt;
}
void dfs(int u)
{
int v;
pre[u]=lowlink[u]=++dfs_clock;
mstack[++stack_cnt]=u;
for(int i=first[u];i;i=e[i].nxt){
v=e[i].v;
if(!pre[v]){
dfs(v);
lowlink[u]=min(lowlink[u],lowlink[v]);
}
else if(!sccn[v])
lowlink[u]=min(lowlink[u],pre[v]);
}
if(!(pre[u]^lowlink[u])){
hd[++scc_cnt]=u;
do{
v=mstack[stack_cnt--];
sccn[v]=scc_cnt;
++sz[scc_cnt];
}while(v^u);
}
}
void tarjan()
{
memset(pre,0,sizeof(pre));
memset(sccn,0,sizeof(sccn));
memset(lowlink,0,sizeof(lowlink));
stack_cnt=dfs_clock=scc_cnt=0;
for(int i=1;i<=n;i++)
if(!pre[i])
dfs(i);
}
bool jud(int u)
{
for(int i=first[u];i;i=e[i].nxt)
if(du[sccn[e[i].v]]==1)
return 0;
return 1;
}
int main()
{
memset(sz,0,sizeof(sz));
memset(du,0,sizeof(du));
memset(first,0,sizeof(first));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
link(u,v);
}
tarjan();
for(int i=1;i<=ecnt;i++)
if(sccn[e[i].u]^sccn[e[i].v])
++du[sccn[e[i].v]];
for(int i=1;i<=scc_cnt;i++)
if(!du[i])
++ans;
for(int i=1;i<=scc_cnt;i++)//special judge;
if(!du[i]&&sz[i]==1&&jud(hd[i]))
{--ans;break;}
printf("%.6lf\n",(double)(n-ans)/n);
return 0;
}

bzoj2438[中山市选2011]杀人游戏的更多相关文章

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

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

  2. BZOJ2438:[中山市选2011]杀人游戏(强连通分量)

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

  3. BZOJ2438: [中山市选2011]杀人游戏(tarjan)

    题意 题目链接 Sol 这题挺考验阅读理解能力的.. 如果能读懂的话,不难发现这就是在统计有多少入度为\(0\)的点 缩点后判断一下即可 当然有一种例外情况是\(1 -> 3, 2 -> ...

  4. BZOJ_2438_[中山市选2011]杀人游戏 _强连通分量

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

  5. 【bzoj2438】 中山市选2011—杀人游戏

    http://www.lydsy.com/JudgeOnline/problem.php?id=2438 (题目链接) 题意 n个点的有向图,其中有一个是杀手,每个人成为杀手的概率相同.警察询问一个人 ...

  6. 【BZOJ2438】 [中山市选2011]杀人游戏 tarjan强连通分量+缩点

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

  7. 【bzoj2438】[中山市选2011]杀人游戏 Tarjan

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

  8. BZOJ 2438: [中山市选2011]杀人游戏

    Description 给你一个有向图,求至少询问多少次能够得到全部点的信息. Sol Tarjan + 强连通分量缩点 + 判断. 先缩点,如果我们知道了强连通分量里的任意一个点,我们就可以知道这些 ...

  9. bzoj 2438 [中山市选2011]杀人游戏(SCC+概率)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2438 [题意] N个人中有一个杀手,每次询问一个人可能被杀或被告知其认识的人中谁是杀手 ...

随机推荐

  1. vncserver安装

    我的环境是centos6.5,如果没有安装桌面,先执行: # yum groupinstall "X Window System" "Desktop" # yu ...

  2. 8款超实用JavaScript框架

    下面盘点了8款实用的JavaScript框架: 1. Hammer.js Hammer.js是被广泛使用的轻量级JavaScript框架,它提供了常用触摸操作的规范,比如收缩.拖放.双击和删除等等.它 ...

  3. Tint(着色器)的兼容实现

    我们在做控件的时候可以使用tint这个属性给控件上色,这样在很多情况下能减少不同色彩的资源色彩.在MD设计中,控件颜色随着主体改变也是一大要点,今天我们就来看看如何使用它. 使用步骤:1.建立一个控件 ...

  4. Android中的Touch事件

    Android中的Touch事件处理 主要内容 Activity或View类的onTouchEvent()回调函数会接收到touch事件. 一个完整的手势是从ACTION_DOWN开始,到ACTION ...

  5. Android 在C代码中调用logcat

    本文给<Android java传递int类型数组给C>中添加C代码中调用logcat的功能 Android.mk文件增加以下内容 LOCAL_LDLIBS += -llog C代码中增加 ...

  6. 【读书笔记】iOS网络-解析响应负载

    Web Service可以通过多种格式返回结构化数据, 不过大多数时候使用的是XML与JSON.也可以让应用只接收HTML结构的数据.实现了这些Web Service或是接收HTML文档的应用必须能解 ...

  7. 开篇:IT软件人员学习的书籍 - IT软件人员书籍系列文章

    读书是一件快乐的事情. 读书能够增长知识,了解社会,了解人类的思想,继而转换成智慧.无论是什么人,都需要读书,多读书,读好书,同时也要把书中的精髓记录下来,一个是当做读后感,一个是为以后如果忘记了回头 ...

  8. git代码库误操作还原记录

    先做一些前情提要: 我们项目使用git作为代码管理,同时为了操作更方便,安装了乌龟git(tortoiseGit)工具.以下几乎所有操作都是在乌龟git上进行. 我们的项目是分阶段完成的,在完成上一阶 ...

  9. 《CLR via C#》读书笔记--基元类型、引用类型和值类型

    编程语言的基元类型 编译器直接支持的数据类型称为基元类型.基元类型直接映射到Framework类库中存在的类型.例如:C#中的int直接映射到System.Int32类型.下表给出了C#基元类型与对应 ...

  10. C# 多线程,论多核时代爱恨情仇

    为什么要学习多线程? 2010年1月21日是10年某市公务员考试的报名截止日.因从下午2点开始,用于报名的北京市人事考试网瘫痪,原定于昨天下午5点截止的报名时间延迟至今天上午11点. 2011年3月1 ...