bzoj千题计划289:bzoj 2707: [SDOI2012]走迷宫
http://www.lydsy.com/JudgeOnline/problem.php?id=2707
dp[i] 表示从点i到终点的期望步数
dp[i]= Σ (dp[j]+1)/out[i]
j表示i的出边指向的店,out[i] 表示i的出边数
如果图是一张DAG,那么直接在反图 上 拓扑排序DP即可
现在有环,那就缩点,环上的用高斯消元
无解的情况:
1、起点走不到终点
2、存在一个联通块,起点能走到他,但这个联通块没有出边,且不是终点所在的联通块
因为此时一旦步入这个联通块将永远走不出去
#include<cmath>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<algorithm>
#include<iostream> #define N 10001
#define M 1000001 using namespace std; int front[N],to[M],nxt[M],tot;
int front_[N],to_[M],nxt_[M],tot_; int dfn[N],low[N],id;
int st[N],top;
bool vis[N]; vector<int>block[N];
int bl[N],cnt;
int num[N]; double out[N];
int in_[N]; bool vis_block[N]; double a[][],dp[N]; queue<int>q; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
to_[++tot_]=u; nxt_[tot_]=front_[v]; front_[v]=tot_;
} void tarjan(int x)
{
dfn[x]=low[x]=++id;
st[++top]=x;
vis[x]=true;
for(int i=front[x];i;i=nxt[i])
if(!dfn[to[i]])
{
tarjan(to[i]);
low[x]=min(low[x],low[to[i]]);
}
else if(vis[to[i]]) low[x]=min(low[x],dfn[to[i]]);
if(dfn[x]==low[x])
{
cnt++;
while(st[top]!=x)
{
block[cnt].push_back(st[top]);
bl[st[top]]=cnt;
num[st[top]]=block[cnt].size()-;
vis[st[top--]]=false;
}
block[cnt].push_back(x);
bl[x]=cnt;
num[x]=block[cnt].size()-;
vis[st[top--]]=false;
}
} void dfs(int x)
{
vis[x]=vis_block[bl[x]]=true;
for(int i=front[x];i;i=nxt[i])
if(!vis[to[i]]) dfs(to[i]);
} void gauss(int n)
{
int r; double t;
for(int i=;i<n;++i)
{
r=i;
for(int j=i+;j<n;++j)
if(fabs(a[j][i])>fabs(a[r][i])) r=j;
if(r!=i)
for(int j=;j<=n;++j) swap(a[r][j],a[i][j]);
for(int k=i+;k<n;++k)
{
t=a[k][i]/a[i][i];
for(int j=i;j<=n;++j) a[k][j]-=t*a[i][j];
}
}
for(int i=n-;i>=;--i)
{
for(int j=i+;j<n;++j) a[i][n]-=a[i][j]*a[j][n];
a[i][n]/=a[i][i];
}
} int main()
{
int n,m,s,t;
read(n); read(m); read(s); read(t);
int u,v;
for(int i=;i<=m;++i)
{
read(u); read(v);
add(u,v); out[u]++;
}
for(int i=;i<=n;++i)
if(!dfn[i]) tarjan(i);
dfs(s);
if(!vis[t])
{
printf("INF");
return ;
}
for(int i=;i<=n;++i)
for(int j=front[i];j;j=nxt[j])
if(bl[i]!=bl[to[j]]) in_[bl[i]]++;
for(int i=;i<=cnt;++i)
if(vis_block[i] && !in_[i] && i!=bl[t])
{
printf("INF");
return ;
}
for(int i=;i<=n;++i) out[i]=1.0/out[i];
q.push(bl[t]);
int now,siz,x;
while(!q.empty())
{
now=q.front();
q.pop();
memset(a,,sizeof(a));
siz=block[now].size();
for(int i=;i<siz;++i)
{
x=block[now][i];
a[i][i]=;
a[i][siz]=dp[x];
if(x==t) continue;
for(int j=front[x];j;j=nxt[j])
if(bl[to[j]]==now)
{
a[i][siz]+=out[x];
a[i][num[to[j]]]-=out[x];
}
}
gauss(siz);
for(int i=;i<siz;++i)
{
x=block[now][i];
dp[x]=a[i][siz];
for(int j=front_[x];j;j=nxt_[j])
if(bl[to_[j]]!=now)
{
--in_[bl[to_[j]]];
if(!in_[bl[to_[j]]]) q.push(bl[to_[j]]);
dp[to_[j]]+=(dp[x]+)*out[to_[j]];
}
}
}
printf("%.3lf",dp[s]);
}
bzoj千题计划289:bzoj 2707: [SDOI2012]走迷宫的更多相关文章
- BZOJ 2707: [SDOI2012]走迷宫( tarjan + 高斯消元 )
数据范围太大不能直接高斯消元, tarjan缩点然后按拓扑逆序对每个强连通分量高斯消元就可以了. E(u) = 1 + Σ E(v) / degree(u) 对拍时发现网上2个程序的INF判断和我不一 ...
- BZOJ 2707: [SDOI2012]走迷宫 [高斯消元 scc缩点]
2707: [SDOI2012]走迷宫 题意:求s走到t期望步数,\(n \le 10^4\),保证\(|SCC| \le 100\) 求scc缩点,每个scc高斯消元,scc之间直接DP 注意每次清 ...
- bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块
http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...
- bzoj千题计划196:bzoj4826: [Hnoi2017]影魔
http://www.lydsy.com/JudgeOnline/problem.php?id=4826 吐槽一下bzoj这道题的排版是真丑... 我还是粘洛谷的题面吧... 提供p1的攻击力:i,j ...
- bzoj千题计划317:bzoj4650: [Noi2016]优秀的拆分(后缀数组+差分)
https://www.lydsy.com/JudgeOnline/problem.php?id=4650 如果能够预处理出 suf[i] 以i结尾的形式为AA的子串个数 pre[i] 以i开头的形式 ...
- bzoj千题计划209:bzoj1185: [HNOI2007]最小矩形覆盖
http://www.lydsy.com/JudgeOnline/problem.php?id=1185 题解去看它 http://www.cnblogs.com/TheRoadToTheGold/p ...
- bzoj千题计划121:bzoj1033: [ZJOI2008]杀蚂蚁antbuster
http://www.lydsy.com/JudgeOnline/problem.php?id=1033 经半个下午+一个晚上+半个晚上 的 昏天黑地调代码 最终成果: codevs.洛谷.tyvj上 ...
- bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪
http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...
- bzoj千题计划177:bzoj1858: [Scoi2010]序列操作
http://www.lydsy.com/JudgeOnline/problem.php?id=1858 2018 自己写的第1题,一遍过 ^_^ 元旦快乐 #include<cstdio> ...
随机推荐
- 你应该知道Go语言的几个优势
要说起GO语言的优势,我们就得从GO语言的历史讲起了-- 本文由腾讯技术工程官方号发表在腾讯云+社区 2007年,受够了C++煎熬的Google首席软件工程师Rob Pike纠集Robert Grie ...
- 2018-07-09--记录一次gitlab迁移事件及遇到的问题
一.事情起因 因机房服务器即将到期,需要将即将到期的服务器迁移至云上,迁移之前没有查看老环境的Gitlab是什么版本,直接装的Gitlab社区版,做数据导入时提示版本错误: [root@vpn-ser ...
- 机器学习初入门02 - Pandas的基本操作
之前的numpy可以说是一个针对矩阵运算的库,这个Pandas可以说是一个实现数据处理的库,Pandas底层的许多函数正是基于numpy实现的 一.Pandas数据读取 1.pandas.read_c ...
- “Linux内核分析”实验二报告
张文俊 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.第二周学习内 ...
- 《Spring2之站立会议10》
<Spring2之站立会议10> 昨天,添加完了表情库: 今天,对整个项目进行了测试: 遇到的问题:测试后觉得有些方面还不足,需要进一步改进.
- Hadoop 4 MapReduce
对单词个数统计的MapReduce的案例 Mapper类: package main.java.worldClient; import java.io.IOException; import org. ...
- vs2013的安装及测试(第三周)
1.打开同学给的安装包,发现如下问题: 2.因为是win7,提示需安装IE10.因为安装IE10必须要在安装好 server pack 1的情况下,所以从官方网站上下载好server pack 1,并 ...
- Win 2008 r2 远程桌面多用户登陆,一用户多登陆配置
Windows 2008 R2远程桌面,设置最大连接数,一个登录后另一个就被踢掉等问题 Windows 2008 R2配置如图: 1.打开远程桌面回话主机配置 2.右键RDP-Tcp,属性,可设置最大 ...
- 把Excel转换成DataTable,Excel2003+
在数据处理的时候,我们会Excel(包含2003.2007.2010等)转换成DataTable,以便进一步操作 1.怎么访问Excel文件呢?我们可以通过OLEDB接口访问,如下: private ...
- ElasticSearch 2 (14) - 深入搜索系列之全文搜索
ElasticSearch 2 (14) - 深入搜索系列之全文搜索 摘要 在看过结构化搜索之后,我们看看怎样在全文字段中查找相关度最高的文档. 全文搜索两个最重要的方面是: 相关(relevance ...