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> ...
随机推荐
- 带WIFI模块布局布线要点。
带WIFI模块布局布线要求: 1: RF底部不能铺铜要挖空不能有GND否则RF信号会被耦合掉从而无法发送出去. 2:WIFI模块下方不能打孔尽量不走线不打孔避开其他信号穿过下方,要整体的铺铜 3:连接 ...
- redis启动停止+密码认证
redis启动停止命令 ./bin/redis-server redis.conf ./bin/redis-cli -h 127.0.0.1 -p 6379 shutdown flushall ——& ...
- 【MOOC EXP】Linux内核分析实验三报告
程涵 原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 [跟踪分析Linux内核的启动过程] ...
- 作业6小学生四则运算测试APP的NABCD模型
小学生四则运算测试NABCD模型 组员:李新,朱浩龙,叶煜稳,陈俊金,林德麟 (1) N (Need 需求) 需求分析: 四则运算是小学生学习数学的核心和基础,必须经过大量的练习才能熟练掌握,但是一 ...
- 20190215面试-C#操作外设-多线程-shocket
百度了下,ic卡读卡器 文章;C# 读IC卡程序这个文章还不错. 从北京金木雨电子有限公司下载了,兼容IC卡 身份证阅读器的SDK资料,里面有介绍如何连接ic读卡器,对卡进行一些操作. MasterR ...
- 『编程题全队』Alpha阶段事后诸葛亮分析
一.设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? Answer: (1)我们软件主要解决个人和团队的事务管理问题 (2)我们软件的定义明确和清楚 ...
- Alpha 冲刺十
团队成员 051601135 岳冠宇 051604103 陈思孝 031602629 刘意晗 031602248 郑智文 031602234 王淇 会议照片 项目燃尽图 项目进展 完善各自部分 项目描 ...
- 页面用一个遮罩层显示加载,加载完后隐藏该div
<div id="background" class="background" style="display: none; "> ...
- java学习二 数据类型自动提升 0x开头的数据是 16进制且是int型
变量只能定义一次,不能定义两次, 变量的作用域:当前的大括号与子括号才有效 变量的作用:存储值,取值 整型:向上自动升级,向下强制降级 char,byte,shot参与运算时候自动提升为int型 因为 ...
- BZOJ2553 Beijing2011禁忌(AC自动机+动态规划+矩阵快速幂+概率期望)
考虑对一个串如何分割能取得最大值.那么这是一个经典的线段覆盖问题,显然每次取右端点尽量靠前的串.于是可以把串放在AC自动机上跑,找到一个合法串后就记录并跳到根. 然后考虑dp.设f[i][j]表示前i ...