题面

Morenan被困在了一个迷宫里。迷宫可以视为N个点M条边的有向图,其中Morenan处于起点S,迷宫的终点设为T。可惜的是,Morenan非常的脑小,他只会从一个点出发随机沿着一条从该点出发的有向边,到达另一个点。这样,Morenan走的步数可能很长,也可能是无限,更可能到不了终点。若到不了终点,则步数视为无穷大。但你必须想方设法求出Morenan所走步数的期望值。

N<=10000,M<=1000000,保证强连通分量的大小不超过 200。

题解

做法没什么好细说的,

就是缩点,然后按照拓扑序倒着求每个强连通分量的 DP 值(每个点出发的期望步数),强连通分量内部用高斯消元。如果存在概率走入一个死环(无法走到终点的强连通分量),那么就无穷大。

剩下的就是一些细节:

没必要真的求拓扑序,只需要按照 dfs 序倒着来,也就是 Tarjan 缩点产生强连通分量的正顺序来就行了。

解方程如果无解,说明期望步数无穷大。

解方程之前注意清空(包括 size+1 列),注意各种标号。

CODE

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 1000005
#define LL long long
#define DB double
#define lowbit(x) (-(x) & (x))
#define ENDL putchar('\n')
#define FI first
#define SE second
#define eps 1e-9
LL read() {
LL f=1,x=0;int s = getchar();
while(s < '0' || s > '9') {if(s<0) return -1;if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s^48);s = getchar();}
return f*x;
}
void putpos(LL x) {if(!x)return ;putpos(x/10);putchar('0'+(x%10));}
void putnum(LL x) {
if(!x) {putchar('0');return ;}
if(x<0) {putchar('-');x = -x;}
return putpos(x);
}
void AIput(LL x,int c) {putnum(x);putchar(c);} const int MOD = 1000000007;
int n,m,s,o,k;
int od[MAXN],S,T;
int hd[MAXN],v[MAXN<<1],nx[MAXN<<1],cne;
void ins(int x,int y) {
nx[++ cne] = hd[x]; v[cne] = y; hd[x] = cne;
}
int dfn[MAXN],low[MAXN],tim;
bool f[MAXN];
int fail[MAXN];
stack<int> st;
int bel[MAXN],cnt;
vector<int> bu[MAXN];
int rk[MAXN];
void dfs0(int x) {
low[x] = dfn[x] = ++ tim;
st.push(x); f[x] = 1;
for(int i = hd[x];i;i = nx[i]) {
int y = v[i];
if(!dfn[y]) {
dfs0(y);
low[x] = min(low[x],low[y]);
}
else if(f[y]) {
low[x] = min(low[x],dfn[y]);
}
}
if(low[x] == dfn[x]) {
fail[++ cnt] = -1;
while(f[x]) {
int t = st.top(); st.pop();
f[t] = 0;
bel[t] = cnt;
bu[cnt].push_back(t);
rk[t] = bu[cnt].size();
}
}
return ;
}
DB a[205][205],dp[MAXN];
DB Abs(DB x) {return x < 0 ? -x:x;}
int Gauss(int n) {
for(int i = 1;i <= n;i ++) {
for(int j = i+1;j <= n;j ++) {
if(Abs(a[j][i]) > Abs(a[i][i])) {
swap(a[i],a[j]);
}
}
if(Abs(a[i][i]) < eps) continue;
for(int j = i+1;j <= n;j ++) {
DB nm = a[j][i] / a[i][i];
for(int k = n+1;k >= i;k --) {
a[j][k] -= a[i][k] * nm;
}
}
}
for(int i = n;i > 0;i --) {
for(int j = n;j > i;j --) {
a[i][n+1] -= a[i][j] * a[j][n+1];
a[i][j] = 0;
}
if(!a[i][i]) return 1;
a[i][n+1] /= a[i][i];
a[i][i] = 1;
}
return 0;
}
int main() {
n = read(); m = read();
S = read(); T = read();
for(int i = 1;i <= m;i ++) {
s = read();o = read();
ins(s,o); od[s] ++;
}
for(int i = 1;i <= n;i ++) {
if(!dfn[i]) {
dfs0(i);
}
}
for(int i = 1;i <= cnt;i ++) {
int sz = bu[i].size();
for(int j = 1;j <= sz;j ++) {
for(int k = 1;k <= sz+1;k ++) a[j][k] = 0;
}
for(int j = 1;j <= sz;j ++) {
a[j][j] = 1.0;
}
for(int j = 0;j < sz;j ++) {
int x = bu[i][j];
if(x == T) continue;
if(!od[x]) {
fail[i] = 1; break;
}
a[rk[x]][sz+1] += 1.0;
for(int k = hd[x];k;k = nx[k]) {
int y = v[k];
if(y == T) a[rk[x]][sz+1] += 1.0/od[x] * dp[T];
else if(bel[y] != i) {
if(fail[bel[y]] > 0) {fail[i] = 1;break;}
a[rk[x]][sz+1] += 1.0/od[x] * dp[y];
}
else {
a[rk[x]][rk[y]] -= 1.0/od[x];
}
}
if(fail[i] > 0) break;
}
if(fail[i] > 0) continue;
fail[i] = Gauss(sz);
for(int j = 0;j < sz;j ++) {
int x = bu[i][j];
dp[x] = a[rk[x]][sz+1];
}
}
if(fail[bel[S]] > 0) printf("INF\n");
else printf("%.3f\n",dp[S]);
return 0;
}
``

[SDOI2012]走迷宫 (强连通分量缩点,动态规划,高斯消元)的更多相关文章

  1. BZOJ_1778_[Usaco2010_Hol]_Dotp_驱逐猪猡_(期望动态规划+高斯消元+矩阵)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1778 炸弹从1出发,有\(\frac{P}{Q}\)的概率爆炸,如果不爆炸,等概率移动到连通的 ...

  2. 洛谷 P5643 - [PKUWC2018]随机游走(Min-Max 容斥+FWT+树上高斯消元,hot tea)

    题面传送门 一道挺综合的 hot tea,放到 PKUWC 的 D2T2 还挺喜闻乐见的( 首先我们考虑怎样对一个固定的集合 \(S\) 计算答案,注意到我们要求的是一个形如 \(E(\max(S)) ...

  3. BZOJ_3270_博物馆_(高斯消元+期望动态规划+矩阵)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3270 \(n\)个房间,刚开始两个人分别在\(a,b\),每分钟在第\(i\)个房间有\(p[ ...

  4. uva 11324 The Largest Clique(强连通分量缩点+DAG动态规划)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=25&page=sh ...

  5. BZOJ 2707: [SDOI2012]走迷宫 [高斯消元 scc缩点]

    2707: [SDOI2012]走迷宫 题意:求s走到t期望步数,\(n \le 10^4\),保证\(|SCC| \le 100\) 求scc缩点,每个scc高斯消元,scc之间直接DP 注意每次清 ...

  6. 洛谷 P6030 - [SDOI2012]走迷宫(高斯消元+SCC 缩点)

    题面传送门 之所以写个题解是因为题解区大部分题解的做法都有 bug(u1s1 周六上午在讨论区里连发两个 hack 的是我,由于我被禁言才让 ycx 代发的) 首先碰到这种期望题,我们套路地设 \(d ...

  7. BZOJ 2707: [SDOI2012]走迷宫( tarjan + 高斯消元 )

    数据范围太大不能直接高斯消元, tarjan缩点然后按拓扑逆序对每个强连通分量高斯消元就可以了. E(u) = 1 + Σ E(v) / degree(u) 对拍时发现网上2个程序的INF判断和我不一 ...

  8. 【BZOJ2707】[SDOI2012]走迷宫 Tarjan+拓扑排序+高斯消元+期望

    [BZOJ2707][SDOI2012]走迷宫 Description Morenan被困在了一个迷宫里.迷宫可以视为N个点M条边的有向图,其中Morenan处于起点S,迷宫的终点设为T.可惜的是,M ...

  9. BZOJ2707 [SDOI2012]走迷宫 【概率dp + tarjan + 高斯消元】

    题目 Morenan被困在了一个迷宫里.迷宫可以视为N个点M条边的有向图,其中Morenan处于起点S,迷宫的终点设为T.可惜的是,Morenan非常的脑小,他只会从一个点出发随机沿着一条从该点出发的 ...

随机推荐

  1. 如何通过A/B测试提升Push推送消息点击率?

    618电商节火热进行中,某电商App准备向用户推送一条全局活动消息,运营准备了两个推送文案: 文案A:年中囤货我们更懂你,没有大优惠怎敢惊动你:美妆个户,户外运动,医疗健康,一站式备齐,点击>& ...

  2. Python中plt.plot()、plt.scatter()和plt.legend函数的用法示例

    参考:http://www.cppcns.com/jiaoben/python/471948.html https://blog.csdn.net/weixin_44825185/article/de ...

  3. PyTorch DataLoader NumberWorkers Deep Learning Speed Limit Increase

    这意味着训练过程将按顺序在主流程中工作. 即:run.num_workers.   ,此外, ,因此,主进程不需要从磁盘读取数据:相反,这些数据已经在内存中准备好了. 这个例子中,我们看到了20%的加 ...

  4. 【FAQ】运动健康服务REST API接口使用过程中常见问题和解决方法总结

    华为运动健康服务(HUAWEI Health Kit)为三方生态应用提供了REST API接口,通过其接口可访问数据库,为用户提供运动健康类数据服务.在实际的集成过程中,开发者们可能会遇到各种问题,这 ...

  5. 2 万字 + 30 张图 | 细聊 MySQL undo log、redo log、binlog 有什么用?

    作者:小林coding 计算机八股文网站:https://xiaolincoding.com/ 大家好,我是小林. 从这篇「执行一条 SQL 查询语句,期间发生了什么?」中,我们知道了一条查询语句经历 ...

  6. distroless 镜像介绍及 基于cbl-mariner的.NET distroless 镜像的容器

    1.概述 容器改变了我们看待技术基础设施的方式.这是我们运行应用程序方式的一次巨大飞跃.容器编排和云服务一起为我们提供了一种近乎无限规模的无缝扩展能力. 根据定义,容器应该包含 应用程序 及其 运行时 ...

  7. Leetcode--Last Stone Weight II

    Last Stone Weight II 欢迎关注H寻梦人公众号 You are given an array of integers stones where stones[i] is the we ...

  8. NC23046 华华教月月做数学

    NC23046 华华教月月做数学 题目 题目描述 找到了心仪的小姐姐月月后,华华很高兴的和她聊着天.然而月月的作业很多,不能继续陪华华聊天了.华华为了尽快和月月继续聊天,就提出帮她做一部分作业. 月月 ...

  9. 微信开发在Pc端调用公众号粉丝发送过来的图片素材

    因为项目要在PC端搞一个微信墙功能,就是把粉丝发送过来的上墙内容给展示出来,但因为微信对微信素材进行了防盗链加密处理,所以在非微信页面上直接引用在微信服务器上的图片的链接是无法显示的,只会显示一张微信 ...

  10. 服务器宕机了,Kafka 消息会丢失吗?

    大家好,我是树哥. 消息队列可谓是高并发下的必备中间件了,而 Kafka 作为其中的佼佼者,经常被我们使用到各种各样的场景下.随着 Kafka 而来得,还有三个问题:消息丢失.消息重复.消息顺序.今天 ...