BZOJ 2707: [SDOI2012]走迷宫 [高斯消元 scc缩点]
2707: [SDOI2012]走迷宫
题意:求s走到t期望步数,\(n \le 10^4\),保证\(|SCC| \le 100\)
求scc缩点,每个scc高斯消元,scc之间直接DP
注意每次清空系数矩阵
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e4+5, M=1e6+5;
const double eps=1e-8;
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
int n, m, s, t, de[N], u, v;
struct edge{int v, ne;} e[M];
int cnt=1, h[N];
inline void ins(int u, int v) {e[++cnt]=(edge){v, h[u]}; h[u]=cnt;}
int dfn[N], low[N], dfc, belong[N], scc;
struct List{
int a[105], n;
int& operator [](int x) {return a[x];}
inline void push(int x) {a[++n]=x;}
}li[N];
int st[N], top;
void dfs(int u) { //printf("dfs %d\n",u);
dfn[u] = low[u] = ++dfc;
st[++top] = u;
for(int i=h[u];i;i=e[i].ne) {
int v=e[i].v;
if(!dfn[v]) dfs(v), low[u] = min(low[u], low[v]);
else if(!belong[v]) low[u] = min(low[u], dfn[v]);
}
if(dfn[u] == low[u]) {
scc++;
while(true) {
int x=st[top--];
belong[x] = scc;
li[scc].push(x);
if(x == u) break;
}
}
}
double a[105][105], f[N]; int id[N];
void gauss(int n) {
//puts("\ngauss");
//for(int i=1; i<=n; i++)
// for(int j=1; j<=n+1; j++) printf("%lf%c",a[i][j], j==n+1 ? '\n' : ' ');
for(int i=1; i<=n; i++) {
int r=i;
for(int j=i; j<=n; j++) if(abs(a[j][i])>abs(a[r][i])) r=j;
if(r!=i) for(int j=1; j<=n+1; j++) swap(a[r][j], a[i][j]);
for(int k=i+1; k<=n; k++) if(abs(a[k][i]) > eps){
double t = a[k][i]/a[i][i];
for(int j=i; j<=n+1; j++) a[k][j] -= t*a[i][j];
}
}
for(int i=n; i>=1; i--) {
for(int j=n; j>i; j--) a[i][n+1] -= a[i][j]*a[j][n+1];
a[i][n+1] /= a[i][i];
}
}
void solve(List &q) {
memset(a,0,sizeof(a));
int n=0;
for(int i=1; i<=q.n; i++) id[q[i]] = ++n;// printf("%d ",q[i]); puts(" q");
for(int i=1; i<=q.n; i++) {
int u=q[i];
a[i][i]=1; a[i][n+1]=1;
if(u==t) {a[i][n+1]=0; continue;}
for(int p=h[u];p;p=e[p].ne) {
int v=e[p].v;
if(belong[v] != belong[u]) a[i][n+1] += f[v]/de[u];
else a[i][id[v]] -= 1.0/de[u];
}
}
gauss(n);
for(int i=1; i<=q.n; i++) f[q[i]] = a[i][n+1];// printf("getf %d %lf\n",q[i],f[q[i]]);
}
namespace SCC {
struct edge{int v, ne;} e[M];
int cnt=1, h[N];
inline void ins(int u, int v) {e[++cnt]=(edge){v, h[u]}; h[u]=cnt;}
int vis[N];
void dfs(int u) {
if(vis[u]) return; vis[u]=1;
for(int i=h[u];i;i=e[i].ne) dfs(e[i].v);
//printf("solveSCC %d\n",u);
solve(li[u]);
}
}
void build() {
for(int u=1; u<=n; u++)
for(int i=h[u];i;i=e[i].ne)
if(belong[u] != belong[e[i].v]) SCC::ins(belong[u], belong[e[i].v]);
}
int main() {
freopen("in","r",stdin);
n=read(); m=read(); s=read(); t=read();
for(int i=1; i<=m; i++) {
u=read(), v=read();
de[u]++; ins(u, v);
}
dfs(s);
//for(int i=1; i<=n; i++) printf("scc %d %d %d\n",i, dfn[i], belong[i]);
if(!dfn[t]) {puts("INF"); return 0;}
for(int i=1; i<=n; i++) if(i!=t && de[i]==0 && dfn[i]) {puts("INF"); return 0;}
build();
SCC::dfs(belong[s]);
//for(int i=1; i<=n; i++) printf("f %d %lf\n",i,f[i]);
printf("%.3lf", f[s]);
}
BZOJ 2707: [SDOI2012]走迷宫 [高斯消元 scc缩点]的更多相关文章
- BZOJ 2707: [SDOI2012]走迷宫( tarjan + 高斯消元 )
数据范围太大不能直接高斯消元, tarjan缩点然后按拓扑逆序对每个强连通分量高斯消元就可以了. E(u) = 1 + Σ E(v) / degree(u) 对拍时发现网上2个程序的INF判断和我不一 ...
- BZOJ.2707.[SDOI2012]走迷宫(期望 Tarjan 高斯消元)
题目链接 一个点到达终点的期望步数 \(E_i=\sum_{(i,j)\in G}\frac{E_j+1}{out[i]}\),\(out[i]\)为点\(i\)的出度. 那么对于一个DAG可以直接在 ...
- bzoj 2707 [SDOI2012]走迷宫(SCC+高斯消元)
Description Morenan被困在了一个迷宫里.迷宫可以视为N个点M条边的有向图,其中Morenan处于起点S,迷宫的终点设为T.可惜的是,Morenan非常的脑小,他只会从一个点出发随机沿 ...
- BZOJ 2707: [SDOI2012]走迷宫 拓扑+高斯消元+期望概率dp+Tarjan
先Tarjan缩点 强连通分量里用高斯消元外面直接转移 注意删掉终点出边和拓扑 #include<cstdio> #include<cstring> #include<a ...
- 洛谷 P6030 - [SDOI2012]走迷宫(高斯消元+SCC 缩点)
题面传送门 之所以写个题解是因为题解区大部分题解的做法都有 bug(u1s1 周六上午在讨论区里连发两个 hack 的是我,由于我被禁言才让 ycx 代发的) 首先碰到这种期望题,我们套路地设 \(d ...
- 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 ...
- BZOJ 3143 游走(高斯消元)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3143 题意:一个无向连通图,顶点从1编号到n,边从1编号到m.小Z在该图上进行随机游走, ...
- 【BZOJ3143】游走(高斯消元,数学期望)
[BZOJ3143]游走(高斯消元,数学期望) 题面 BZOJ 题解 首先,概率不会直接算... 所以来一个逼近法算概率 这样就可以求出每一条边的概率 随着走的步数的增多,答案越接近 (我卡到\(50 ...
- [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash)
[BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash) 题面 扔很多次硬币后,用H表示正面朝上,用T表示反面朝上,会得到一个硬币序列.比如HTT表示第一次正面朝上, ...
随机推荐
- jsp的内置对象
JSP内置对象即无需声明就可以直接使用的对象实例,在实际的开发过程中,比较常用的JSP对象有request,response,session,out和application等,笔者在本文章中将简单介绍 ...
- tinyxml的封装与使用(转载)
tinyxml是个高效精简的xml解析开源代码. 针对tinyxml直接使用对于对xml不是很熟悉的入门新手来说,有些概念难以理解,因此我将其封装后,供大家使用. 头文件: #include &quo ...
- Python scrapy------分类获取美团整站数据
欢迎联系讨论:qq:1170370113 以下是我们获取美团页面的城市信息 获取到了城市信息以后我们可以进行分类保存,以便于后续能够分类获取数据 获取我们需要城市的景区的所有相关id并且进行保存 最后 ...
- VIM命令模式与输入模式切换
vi编辑器 vi是UNIX和类UNIX环境下的可用于创建文件的屏幕编辑器.vi有两种工作模式:命令模式和文本输入模式.启动vi需要输入vi,按[Spacebar]键并输入文件名后回车. 切换模式键 ...
- No input file specified的解决方法apache伪静态
http://jingyan.baidu.com/article/dca1fa6f8d623ff1a44052e8.html (一)IIS Noinput file specified 方法一:改PH ...
- 查询A、B表中,A表中B表没有的数据
A.B两表,找出ID字段中,存在A表,但是不存在B表的数据.A表总共13w数据,去重后大约3W条数据,B表有2W条数据,且B表的ID字段有索引. 方法一 使用 not in ,容易理解,效率低 ~执 ...
- 读书笔记之《Java编程思想》
17. 容器 Set 存入Set的每个元素都必须是唯一的,因为Set不保存重复元素. Set接口不保证维护元素的次序 Map 映射表(关联数组)的基本思想是维护的是键-值(对)关联,因此可以用键来查找 ...
- MYSQL ORDER BY Optimization
ORDER BY Optimization 某些情况下,MYSQL可以使用index排序而避免额外的sorting. 即使order by语句列不能准确的匹配index,只要没有index中(不在or ...
- 企业级分布式存储应用与实战-mogilefs实现
Mogilefs是什么 MogileFS是一个开源的分布式文件存储系统,由LiveJournal旗下的Danga Interactive公司开发.Danga团队开发了包括 Memcached.Mogi ...
- junit源码解析总结
前面的博客我们也已经整理到了,我们使用junit38,在写测试类的时候我们的测试类必须继承TestCase.这个所有测试类的父类在junit.framework包下面. 前面我们的整理都是说直接在ID ...