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表示第一次正面朝上, ...
随机推荐
- div排版+文档流+定位秘诀
由于没有找到自己认为完整的关于普通流.浮动和绝对定位的中文文章,于是鼓起勇气决定自己来写篇. 在普通流中的 Box(框) 属于一种 formatting context(格式化上下文) ,类型可以是 ...
- Anndroid 使用相机或相册打开图片
安卓操作相机or相册 笔者做这方面测试的时候,没遇到什么大坑基本上,需要注意的有两点 1. 使用相册打开读取图片需要使用运行时权限,而且还是要在AndroidManifest.xml中进行权限声明 ...
- textarea自适应高度,div模仿textarea可编辑实现自适应高度,placeholder使用图标
1.textarea自适应高度,placeholder使用图标 自适应高度,有很多种办法: 1)jq: $("textarea").on("input",fun ...
- 从零开始学习前端开发 — 12、CSS3弹性布局
一.分栏布局 1.设置栏数column-count:数值; 2.设置每栏的宽度column-width:数值+单位; 注:当设置了column-width,column-count会失效,二者设置其一 ...
- b2b2c
编辑 B2B2C是一种电子商务类型的网络购物商业模式,B是BUSINESS的简称,C是CUSTOMER的简称,第一个B指的是商品或服务的供应商,第二个B指的是从事电子商务的企业,C则是表示消费者. ...
- 个人Vue-1.0学习笔记
dVue.js是类似于angular.js的一套构建用户界面的渐进式框架,只关注视图层, 采用自底向上增量开发的设计. Vue.js的代码需要放置在指定的HTML元素后面. 关于Vue的数据绑定: 例 ...
- ngRx 官方示例分析 - 6 - Effect
@ngrx/effect 前面我们提到,在 Book 的 reducer 中,并没有 Search 这个 Action 的处理,由于它需要发出一个异步的请求,等到请求返回前端,我们需要根据返回的结果来 ...
- 将js进行到底:node学习笔记2
node重要API之FS--CLI编程初体验 所谓的"fs"就是file system! 当下几乎任何一门编程语言都会提供对文件系统读写的API,比如c语言的open()函数. 而 ...
- mybatis_SQL映射(1)
文章摘录自:http://blog.csdn.net/y172158950/article/details/17258377 1. select的映射 <select id="sele ...
- pyspider解析
https://www.cnblogs.com/microman/p/6111711.html #!/usr/bin/env python # -*- encoding: utf-8 -*- # Cr ...