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. jsp的内置对象

    JSP内置对象即无需声明就可以直接使用的对象实例,在实际的开发过程中,比较常用的JSP对象有request,response,session,out和application等,笔者在本文章中将简单介绍 ...

  2. Angular 选项卡

    <div ng-init="now=0;" class="nav"> <h4>选项卡</h4> <div > & ...

  3. Solr学习笔记1(V7.2)

    下载压缩包http://archive.apache.org/dist/lucene/,解压后放到某一盘符下面 Windows下启动命令 :\solr-7.2.0>bin\solr.cmd st ...

  4. 一篇文章让你深透理解cookie和session,附带分布式WEB系统redis共享session方案

    cookie和session有什么区别?这是一个很基础的知识点,大家可能都知道一个大概:cookie是存在客户端的,session是存储在服务端,cookie和session用来验证识别用户的登录状态 ...

  5. Rootkit 核心技术——利用 nt!_MDL(内存描述符链表)突破 SSDT(系统服务描述符表)的只读访问限制 Part I

    -------------------------------------------------------- 在 rootkit 与恶意软件开发中有一项基本需求,那就是 hook Windows ...

  6. NSRange 用法

    NSRange的定义 typedef struct _NSRange { NSUInteger location; NSUInteger length; } NSRange; NSRange是一个结构 ...

  7. web前端学习(2):开始编写HTML

    在第一章中,我们初步了解了上网的过程,同时也明白了所谓网页,其本质就是主要用HTML语言所写的一份文档.相信大多数人在了解HTML文件前,最先接触的是利用"记事本"所写的文档或者是 ...

  8. mysql查看表大小

    mysql查看表大小 一:命令 show table status like 'table_name'\G; mysql> show table status like 'x'\G; . row ...

  9. 我的Android手册

    目录解释说明 assets文件说明 app_id:机智云 app id app_secret:机智云 app secret product_key:机智云 product key wifi_type_ ...

  10. Java数据结构和算法(十四)——堆

    在Java数据结构和算法(五)——队列中我们介绍了优先级队列,优先级队列是一种抽象数据类型(ADT),它提供了删除最大(或最小)关键字值的数据项的方法,插入数据项的方法,优先级队列可以用有序数组来实现 ...