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缩点]的更多相关文章

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

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

  2. BZOJ.2707.[SDOI2012]走迷宫(期望 Tarjan 高斯消元)

    题目链接 一个点到达终点的期望步数 \(E_i=\sum_{(i,j)\in G}\frac{E_j+1}{out[i]}\),\(out[i]\)为点\(i\)的出度. 那么对于一个DAG可以直接在 ...

  3. bzoj 2707 [SDOI2012]走迷宫(SCC+高斯消元)

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

  4. BZOJ 2707: [SDOI2012]走迷宫 拓扑+高斯消元+期望概率dp+Tarjan

    先Tarjan缩点 强连通分量里用高斯消元外面直接转移 注意删掉终点出边和拓扑 #include<cstdio> #include<cstring> #include<a ...

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

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

  6. 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 ...

  7. BZOJ 3143 游走(高斯消元)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3143 题意:一个无向连通图,顶点从1编号到n,边从1编号到m.小Z在该图上进行随机游走, ...

  8. 【BZOJ3143】游走(高斯消元,数学期望)

    [BZOJ3143]游走(高斯消元,数学期望) 题面 BZOJ 题解 首先,概率不会直接算... 所以来一个逼近法算概率 这样就可以求出每一条边的概率 随着走的步数的增多,答案越接近 (我卡到\(50 ...

  9. [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash)

    [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash) 题面 扔很多次硬币后,用H表示正面朝上,用T表示反面朝上,会得到一个硬币序列.比如HTT表示第一次正面朝上, ...

随机推荐

  1. '<<' '|' '>>' 等位运算符 课本祥解

    a<<1   相当于a*2     a>>1    相当于a/2   a<<|1   相当于a*2+1 一些算法用得到.

  2. SG 函数 S-Nim

    http://poj.org/problem?id=2960 S-Nim Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 34 ...

  3. find the nth digit(二分查找)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1597 find the nth digit Time Limit: 1000/1000 MS (Jav ...

  4. mysql常用的提权方法

    一,利用MOF提权 Windows 管理规范 (WMI) 提供了以下三种方法编译到 WMI 存储库的托管对象格式 (MOF) 文件: 方法 1: 运行 MOF 文件指定为命令行参数将 Mofcomp. ...

  5. Spring框架学习笔记(7)——代理对象实现AOP

    AOP(面向切面编程) AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming ...

  6. [国嵌笔记][036][关闭MMU和CACHE]

    关闭MMU和CACHE 1.Cache是一种容量小,但存取速度非常快的存储器,它保存最近用到的存储器中数据的拷贝.按功能分为ICache(指令Cache)和DCache(数据Cache) 2.虚拟地址 ...

  7. .28-浅析webpack源码之compiler.resolvers

    原本该在过WebpackOptionsApply时讲解这个方法的,但是当时一不小心过掉了,所以在这里补上. compiler.resolvers 该对象的三个方法均在WebpackOptionsApp ...

  8. 番外篇--Moddule Zero多租户管理

    番外篇--Moddule Zero多租户管理 2.1.1 关于多租户 强烈建议阅读这个文件前阅读多租户文档. 2.1.2 启用多租户 ASP.NET Boilerplate和module-zero可以 ...

  9. 使用phpMyAdmin批量修改Mysql数据表前缀的方法

    多个网站共用一个Mysql数据库时,为使数据库管理不混乱,一般采用不同的网站使用不同前缀名的方式进行区分.而如何批量修改已有数据库的前缀名呢?全部导出修改后再导入?还是一个表一个表的修改?今天我要介绍 ...

  10. Codeforces 900C Remove Extra One 模拟

    题目链接:900C Remove Extra One 题意: 首先record是指这个数比数列前面的所有数都大,给了n个数(1-n),删掉一个数,让整个数列的record值达到最大. 题解: 刚开始我 ...