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]杀人游戏(强联通+特判)的更多相关文章

  1. bzoj2438[中山市选2011]杀人游戏

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

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

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

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

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

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

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

  5. [BZOJ 2438] [中山市选2011]杀人游戏 Tarjan缩点

    这个题很容易想到正解就是缩点找入度为零的点,那么我们考虑一种特殊情况就是,一个入度为零的点我们不访问他就知道他是不是凶手,那么这样的话就是:I. 他是一个真·孤立的点 II. 他在图里但是在他的强联通 ...

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

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

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

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

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

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

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

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

随机推荐

  1. LaTeX 插图片

    本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50240371 这里列出3种LaTeX中 ...

  2. java string遇到的一个奇葩bug

    String abc = "1"; HashMap<String, String> hMap = new HashMap<String, String>() ...

  3. 王立平-bmp.compress()

    bmp.compress(Bitmap.CompressFormat.JPEG, 30, baos); //30 是压缩率,表示压缩70%; 假设不压缩是100,表示压缩率为0

  4. perl getopt 用法

    我们在linux经常常使用到一个程序须要增加參数,如今了解一下perl中的有关控制參数的函数.getopt.在linux有的參数有二种形式.一种是--help,还有一种是-h.也就是-和--的分别.- ...

  5. updatefile.sh - Linux下代码更新脚本

    以下写的是一个关于文件上传的代码shell脚本 该篇文章主要有下面几个方面的考虑: 1.文章主要用于在Linux下代码包批量上传: 2.将被覆盖的代码备份做备份,用于兴许做问题查看或者代码的回退(回退 ...

  6. [jzoj 4668] [NOIP2016提高A组模拟7.19] 腐败 解题报告(质数分类+慢速乘)

    题目链接: http://172.16.0.132/senior/#main/show/4668 题目: 题解: 考虑把A数组里的每个元素分解质因数,对于每个质因数开一个vector存一下包含这个质因 ...

  7. C#线程调用带参数的方法,给控件赋值

    System.Threading.Thread thread = new System.Threading.Thread(() => { //各种业务 //定义一个委托 public deleg ...

  8. highcharts的使用:从数据库获取数据显示在图上

    //月产量统计图 function GetHighCharts() { var date = new Date(); var year = date.getFullYear(); var month_ ...

  9. jq弹窗(获取页面宽高,滚轮高度,始终居中)

    jq写一个弹窗,效果如上图所示, 点击按钮弹窗弹出,右上角关闭. 弹窗始终显示在页面中间,无论放大缩小窗口,滚轮滚动. 代码如下: html: <br><br><br&g ...

  10. row_number函数的使用

    转 row_number函数的使用 SQL Server数据库ROW_NUMBER()函数的使用是本文我们要介绍的内容,接下来我们就通过几个实例来一一介绍ROW_NUMBER()函数的使用. 实例如下 ...