[SDOI2012]走迷宫 (强连通分量缩点,动态规划,高斯消元)
题面
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]走迷宫 (强连通分量缩点,动态规划,高斯消元)的更多相关文章
- BZOJ_1778_[Usaco2010_Hol]_Dotp_驱逐猪猡_(期望动态规划+高斯消元+矩阵)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1778 炸弹从1出发,有\(\frac{P}{Q}\)的概率爆炸,如果不爆炸,等概率移动到连通的 ...
- 洛谷 P5643 - [PKUWC2018]随机游走(Min-Max 容斥+FWT+树上高斯消元,hot tea)
题面传送门 一道挺综合的 hot tea,放到 PKUWC 的 D2T2 还挺喜闻乐见的( 首先我们考虑怎样对一个固定的集合 \(S\) 计算答案,注意到我们要求的是一个形如 \(E(\max(S)) ...
- BZOJ_3270_博物馆_(高斯消元+期望动态规划+矩阵)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3270 \(n\)个房间,刚开始两个人分别在\(a,b\),每分钟在第\(i\)个房间有\(p[ ...
- uva 11324 The Largest Clique(强连通分量缩点+DAG动态规划)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=25&page=sh ...
- BZOJ 2707: [SDOI2012]走迷宫 [高斯消元 scc缩点]
2707: [SDOI2012]走迷宫 题意:求s走到t期望步数,\(n \le 10^4\),保证\(|SCC| \le 100\) 求scc缩点,每个scc高斯消元,scc之间直接DP 注意每次清 ...
- 洛谷 P6030 - [SDOI2012]走迷宫(高斯消元+SCC 缩点)
题面传送门 之所以写个题解是因为题解区大部分题解的做法都有 bug(u1s1 周六上午在讨论区里连发两个 hack 的是我,由于我被禁言才让 ycx 代发的) 首先碰到这种期望题,我们套路地设 \(d ...
- BZOJ 2707: [SDOI2012]走迷宫( tarjan + 高斯消元 )
数据范围太大不能直接高斯消元, tarjan缩点然后按拓扑逆序对每个强连通分量高斯消元就可以了. E(u) = 1 + Σ E(v) / degree(u) 对拍时发现网上2个程序的INF判断和我不一 ...
- 【BZOJ2707】[SDOI2012]走迷宫 Tarjan+拓扑排序+高斯消元+期望
[BZOJ2707][SDOI2012]走迷宫 Description Morenan被困在了一个迷宫里.迷宫可以视为N个点M条边的有向图,其中Morenan处于起点S,迷宫的终点设为T.可惜的是,M ...
- BZOJ2707 [SDOI2012]走迷宫 【概率dp + tarjan + 高斯消元】
题目 Morenan被困在了一个迷宫里.迷宫可以视为N个点M条边的有向图,其中Morenan处于起点S,迷宫的终点设为T.可惜的是,Morenan非常的脑小,他只会从一个点出发随机沿着一条从该点出发的 ...
随机推荐
- Docker容器(centos)安装zabbix
zabbix是一个基于WEB界面提供分布式系统监视以及网络监视功能的企业级的开源解决方案.--百度百科 zabbix介绍 zabbix主要有zabbix-server及zabbix-agent组成,z ...
- 基于.NET6的开源工业物联网网关
什么是工业物联网网关 工业物联网网关(IIoTGateway)是一种硬件设备或软件程序,作为本地设备(如PLC.扫码枪.机器人.数控机床.非标上位机等)与云端系统(如物联网平台.SCADA系统.MES ...
- 深入理解 happens-before 原则
在前面的文章中,我们深入了解了 Java 内存模型,知道了 Java 内存模型诞生的意义,以及其要解决的问题.最终我们知道:Java 内存模型就是定义了 8 个基本操作以及 8 个规则,只要遵守这些规 ...
- tomcat 的安全配置预防后台被攻击
安全是系统架构中最重要的关注点之一,通常情况下,所说的安全涵盖网络安全.数据安全.操作系统安全.服务器安全以及应用系统安全等诸多方面. Tomcat 是一个免费的开放源代码 的Web应用服务器,技术先 ...
- python做小游戏——做个马里奥分分钟解决
一.前言 嗨喽,大家好呀!这里是小熊猫 在你的童年记忆里,是否有一个蹦跳.顶蘑菇的小人已经被遗忘? 马里奥是靠吃蘑菇成长,闻名世界的超级巨星.特征是大鼻子.头戴帽子.身穿背带工作服.还留着胡子.帽子加 ...
- gitlab和jenkins做持续集成构建教程
背景介绍 上一个轮回,我花了三篇文章的时间着重向大家介绍了在条件有限的情况下,如果优雅地进行前端发版和迭代.庆七一,热烈庆祝香港回归,人民生活水平越来越好,昨天上午我自掏腰包买了台服务器,决定由冷兵器 ...
- @RequestMapping注解的属性,将请求约束精细化
package com.atguigu.controller; import org.springframework.stereotype.Controller; import org.springf ...
- ArrayList源码深度剖析,从最基本的扩容原理,到魔幻的迭代器和fast-fail机制,你想要的这都有!!!
ArrayList源码深度剖析 本篇文章主要跟大家分析一下ArrayList的源代码.阅读本文你首先得对ArrayList有一些基本的了解,至少使用过它.如果你对ArrayList的一些基本使用还不太 ...
- 报告指SpaceX估值已达到1000亿美元,埃隆马斯克以此回击其接受政府补贴的批判
SpaceX首席执行官埃隆-马斯克(Elon Musk)表示,名下的航天发射服务供应商市值已达到1000亿美元.该金额是根据上个月的评估报告确认的,标志着SpaceX在完成最新一轮融资,并筹集超过10 ...
- python中的标识符和保留字
保留字,有一些单词被赋予了特定的意义,这些单词不能作为对象的名字 想要快速获取python中的关键字可以通过以下的程 序来快速实现 import keyword print(keyword.kwlis ...