bzoj2438: [中山市选2011]杀人游戏(强联通+特判)
2438: [中山市选2011]杀人游戏
题目:传送门
简要题意:
给出n个点,m条有向边,进行最少的访问并且可以便利(n-1)个点,求这个方案成功的概率
题解:
一道非常好的题目!
题目要知道最大的存活概率,那么也就是找到直接找到杀手的最小概率
那么我们采用强联通缩点:
统计每个联通分量的入度,如果入度为0(证明除此联通分量里的点,没有人可以知道连通分量里的信息,那就一定要先选一个人访问),那么sum++(因为依据题意,假如问到连通分量里的任意一个人,只要ta不是杀手,那么一定可以安全的遍历强联通分量里的所有人)
接下来就是最关键的特判:
对于连通分量里只有一个点的情况,如果它的入度为零,不一定就要访问(这里何前面似乎有些许矛盾)
解释:如果有联通分量只有一个家族成员,并且没有入度,因为杀手只有一个,那么我们完全可以在遍历其他的n-1个点时得出答案(排除法嘛)
但是它的出度不一定为0,所以还要判断一下在上面的基础上,这个点连出去的边是否能够被其他点访问(入度>1),很好理解吧
如果以上的都满足,那么sum--
还有一个小槽点:sum--一次就好了,因为如果有两种相同的情况,那么对于两个独立的点,我们还是要选择一个访问才能遍历完成的
输出1.0-double(sum)/double(n)
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m;
struct node
{
int x,y,next;
}a[];int len,last[];
void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
}
struct edge
{
int x,y,next;
}e[];int len1,last1[];
void inss(int x,int y)
{
len1++;
e[len1].x=x;e[len1].y=y;
e[len1].next=last1[x];last1[x]=len1;
}
int cnt,tp,id;
int belong[],dfn[],low[],sta[],size[];
bool v[];
void dfs(int x)
{
low[x]=dfn[x]=++id;
sta[++tp]=x;v[x]=true;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(dfn[y]==-)
{
dfs(y);
low[x]=min(low[x],low[y]);
}
else
{
if(v[y]==true)
low[x]=min(low[x],dfn[y]);
}
}
if(low[x]==dfn[x])
{
int i;cnt++;
do{
i=sta[tp--];
v[i]=false;
belong[i]=cnt;
size[cnt]++;
}while(i!=x);
}
}
int ru[],chu[],sum1,sum2;
bool check(int x)
{
if(size[x]!=)return true;
if(last1[x]==)return false;
for(int k=last1[x];k;k=e[k].next)
{
int y=e[k].y;
if(ru[y]<=)return true;
}
return false;
}
int main()
{
cnt=tp=id=sum1=sum2=;
len=;len1=;
memset(last,,sizeof(last));memset(last1,,sizeof(last1));
scanf("%d%d",&n,&m);
memset(chu,,sizeof(chu));
memset(ru,,sizeof(ru));
memset(sta,,sizeof(sta));
memset(dfn,-,sizeof(dfn));
memset(low,,sizeof(low));
memset(v,false,sizeof(v));
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
ins(x,y);
}
for(int i=;i<=n;i++)
if(dfn[i]==-)
dfs(i);
for(int i=;i<=m;i++)
{
int st=belong[a[i].x],ed=belong[a[i].y];
if(st!=ed)
{
ru[ed]++;
inss(st,ed);
}
}
for(int i=;i<=cnt;i++)
if(ru[i]==)sum1++;
for(int i=;i<=cnt;i++)
if(ru[i]==)
if(check(i)==false){sum1--;break;}
printf("%.6lf\n",1.0-double(sum1)/double(n));
return ;
}
bzoj2438: [中山市选2011]杀人游戏(强联通+特判)的更多相关文章
- bzoj2438[中山市选2011]杀人游戏
Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面, 查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他 认识的人, ...
- BZOJ2438: [中山市选2011]杀人游戏(tarjan)
题意 题目链接 Sol 这题挺考验阅读理解能力的.. 如果能读懂的话,不难发现这就是在统计有多少入度为\(0\)的点 缩点后判断一下即可 当然有一种例外情况是\(1 -> 3, 2 -> ...
- BZOJ2438:[中山市选2011]杀人游戏(强连通分量)
Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手.警察能够对每一个人 进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是 ...
- BZOJ_2438_[中山市选2011]杀人游戏 _强连通分量
BZOJ_2438_[中山市选2011]杀人游戏 _强连通分量 Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手.警察能够对每一个人 ...
- [BZOJ 2438] [中山市选2011]杀人游戏 Tarjan缩点
这个题很容易想到正解就是缩点找入度为零的点,那么我们考虑一种特殊情况就是,一个入度为零的点我们不访问他就知道他是不是凶手,那么这样的话就是:I. 他是一个真·孤立的点 II. 他在图里但是在他的强联通 ...
- 【bzoj2438】 中山市选2011—杀人游戏
http://www.lydsy.com/JudgeOnline/problem.php?id=2438 (题目链接) 题意 n个点的有向图,其中有一个是杀手,每个人成为杀手的概率相同.警察询问一个人 ...
- 【BZOJ2438】 [中山市选2011]杀人游戏 tarjan强连通分量+缩点
Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是 ...
- 【bzoj2438】[中山市选2011]杀人游戏 Tarjan
题目描述 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是杀手, 谁是平民 ...
- BZOJ 2438: [中山市选2011]杀人游戏
Description 给你一个有向图,求至少询问多少次能够得到全部点的信息. Sol Tarjan + 强连通分量缩点 + 判断. 先缩点,如果我们知道了强连通分量里的任意一个点,我们就可以知道这些 ...
随机推荐
- nginx 查看每秒有多少访问量
nginx访问量统计 1.根据访问IP统计UV awk '{print $1}' access.log|sort | uniq -c |wc -l 2.统计访问URL统计PV awk '{print ...
- cogs 2752. [济南集训 2017] 数列运算
2752. [济南集训 2017] 数列运算 ★★☆ 输入文件:sequenceQBXT.in 输出文件:sequenceQBXT.out 简单对比时间限制:1 s 内存限制:512 ...
- synchronized与static synchronized 的差别、synchronized在JVM底层的实现原理及Java多线程锁理解
本Blog分为例如以下部分: 第一部分:synchronized与static synchronized 的差别 第二部分:JVM底层又是怎样实现synchronized的 第三部分:Java多线程锁 ...
- C++异常注意事项
C++里面catch对于类型转换,限制比参数传递时候要多: 不可以进行标准算术转换和类的自定义转换:在函数参数匹配的过程中,可以进行很多的类型转换.但是在异常匹配的过程中,转换的规则要严厉. 标准算术 ...
- hiho模拟面试题2 补提交卡 (贪心,枚举)
题目: 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描写叙述 小Ho给自己定了一个雄伟的目标:连续100天每天坚持在hihoCoder上提交一个程序.100天过去了.小Ho查 ...
- Android Material Design-Getting Started(入门)-(一)
转载请注明出处:http://blog.csdn.net/bbld_/article/details/40400343 翻译自:http://developer.android.com/trainin ...
- 数据结构 - 树形选择排序 (tree selection sort) 具体解释 及 代码(C++)
树形选择排序 (tree selection sort) 具体解释 及 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 算法逻辑: 依据节点的大小, ...
- Java获取项目路径下的方法(全)
平时敲代码的时候,非常多时候提示文件找不到,而抛出了异常,如今整理例如以下 一 相对路径的获得 说明:相对路径(即不写明时候究竟相对谁)均可通过下面方式获得(不论是一般的java项目还是web项目) ...
- vijos-1382 寻找主人
题意: 给出两个同样长度的数字串: 求两个串是否本质同样.同样则输出最小表示. 长度L似乎给的不正确,大概是2000000左右吧: 题解: 最小表示法裸题.证明正确性啥的详见论文吧: 这东西大体的思路 ...
- CxImage动态加载图片(判断图片文件类型)
1.打开一张图可以通过创建一个新的CxImage对象来完成,通过构造函数来打开一张图CxImage::CxImage(const char * filename, DWORD imagetype)其中 ...