Description

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

Input

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

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

数据已加强!

tarjan求强连通+缩点后,统计入度为0的点,最后特判一下(并不知道为什么)。
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#define N 500500
#define M 500500
using namespace std;
struct data{int next,p;}e1[M],e2[M];
int head1[N],head2[N],belong[N],low[N],dfn[N],mon[N],vscc[N],dis[N],inq[N],vis[N];
int q1[N],q[N];
int n,m,S,p,cnt,ans,qt,scc;
inline int max(int x,int y){return x>y?x:y;}
inline int min(int x,int y){return x<y?x:y;}
inline int read()
{
char c;
int anss=;
while ((c=getchar())==' ' || c=='\n' || c=='\r');
anss=c-'';
while (isdigit(c=getchar())) anss=anss*+c-'';
return anss;
}
void se1(int x,int y){cnt++; e1[cnt].next=head1[x]; head1[x]=cnt; e1[cnt].p=y;}
void se2(int x,int y){cnt++; e2[cnt].next=head2[x]; head2[x]=cnt; e2[cnt].p=y;}
void tarjan(int x)
{
vis[x]=inq[x]=;
dfn[x]=low[x]=++cnt;
q1[++qt]=x;
for (int i=head1[x];i;i=e1[i].next)//i全打成xSB调了好久。
{
if (!vis[e1[i].p])
{
tarjan(e1[i].p);
low[x]=min(low[x],low[e1[i].p]);
}
else if (inq[e1[i].p]) low[x]=min(low[x],low[e1[i].p]);
}
if (low[x]==dfn[x])
{
int now=;
scc++;
while (now!=x)
{
now=q1[qt];qt--;
belong[now]=scc;
inq[now]=;
vscc[scc]+=mon[now];
}
}
}
void part1_tarjan()
{
cnt=;
for (int i=;i<=n;i++)
if (!vis[i]) tarjan(i);
}
void part2_shr_point()
{
cnt=;
for (int i=;i<=n;i++)
for (int j=head1[i];j;j=e1[j].next)
if (belong[i]!=belong[e1[j].p])
se2(belong[i],belong[e1[j].p]);
}
void part3_spfa()
{
memset(inq,,sizeof(inq));
int t=,w=;
q[t]=belong[S];
inq[belong[S]]=;
dis[belong[S]]=vscc[belong[S]];
while (t!=w)
{
int now=q[t];t++;
for (int i=head2[now];i;i=e2[i].next)
if (dis[e2[i].p]<dis[now]+vscc[e2[i].p])
{
dis[e2[i].p]=dis[now]+vscc[e2[i].p];
if (!inq[e2[i].p])
{
inq[e2[i].p]=;
q[w++]=e2[i].p;
}
}
inq[now]=;
}
}
int main()
{
n=read();m=read();
for (int i=;i<=m;i++)
{
int x,y;
x=read();y=read();
se1(x,y);
}
for (int i=;i<=n;i++) mon[i]=read();
part1_tarjan();
part2_shr_point();
S=read();p=read();
part3_spfa();
for (int i=;i<=p;i++)
{
int x=read();
if (dis[belong[x]]>ans) ans=dis[belong[x]];
}
printf("%d\n",ans);
return ;
}

【BZOJ2438】 [中山市选2011]杀人游戏 tarjan强连通分量+缩点的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 【转载】 Pyqt QStackedWidget堆栈窗体

    转载地址: http://blog.csdn.net/a649518776/article/details/6636578 下面用代码实现上面窗口的设计 # -*- coding: utf-8 -*- ...

  2. Sencha Architect 安装与使用

    http://www.sencha.com/products/touch/ Sencha SDK Tools Advanced JavaScript and CSS Project Build Too ...

  3. JqueryDemoTools-用于整理jQueryDemo 分类: C# 公共资源 2014-12-02 16:50 224人阅读 评论(1) 收藏

    应用背景: 在学习js时,为了熟悉某个功能,或使用某个插件,往往需要写一个Demo来测试:一些好的Demo也可以整理积累下来,方便以后查阅: 写了一个编写jQuery Demo的辅助工具.界面很简单, ...

  4. 简单的redis 性能测试

    C:\Users\luhan.qian\Desktop\Tools\redis C:\Users\luhan.qian\Desktop\Tools\redis $ redis-benchmark.ex ...

  5. 2-04使用SQL语句创建数据库

    下面是创建数据库的一些语法: USE master--指向当前使用的数据库 GO--批处理的标志 CREATE DATABASE E_Market--创建E_market数据库 ON PRMARY-- ...

  6. [J2EE] 在Web如何取得相关路径

    来自网络,自己整整一下: request.getRealPath("url"); // 虚拟目录映射为实际目录,不建议使用,使用ServletContext.getRealPath ...

  7. NuGet学习笔记(3) 搭建属于自己的NuGet服务器

    文章导读 创建NuGetServer Web站点 发布站点到IIS 添加本地站点到包包数据源 在上一篇NuGet学习笔记(2) 使用图形化界面打包自己的类库 中讲解了如何打包自己的类库,接下来进行最重 ...

  8. HDU 3586 Information Disturbing 树形DP+二分

    Information Disturbing Problem Description   In the battlefield , an effective way to defeat enemies ...

  9. javase基础笔记3——this关键字和内存图

    什么是面向对象? 面向过程. 面向过程:解决一个问题的思路和方法以及步骤 面向对象:把一些具有相同特征的问题抽象成一个对象,用""""对象.方法()" ...

  10. 遍历CallBack对象 和 HHIVE对象

    内核中有个PLIST_ENTRY CmpHiveListHead;CmpHiveListHead = &CMHIVE.HiveList; CMHIVE结构如下:kd> dt _CMHIV ...