BZOJ 2707: [SDOI2012]走迷宫 [高斯消元 scc缩点]

时间:2022-08-26 20:50:03

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&colon; &lbrack;SDOI2012&rsqb;走迷宫&lpar; tarjan &plus; 高斯消元 &rpar;

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

  2. BZOJ&period;2707&period;&lbrack;SDOI2012&rsqb;走迷宫&lpar;期望 Tarjan 高斯消元&rpar;

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

  3. bzoj 2707 &lbrack;SDOI2012&rsqb;走迷宫(SCC&plus;高斯消元)

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

  4. BZOJ 2707&colon; &lbrack;SDOI2012&rsqb;走迷宫 拓扑&plus;高斯消元&plus;期望概率dp&plus;Tarjan

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

  5. 洛谷 P6030 - &lbrack;SDOI2012&rsqb;走迷宫(高斯消元&plus;SCC 缩点)

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

  6. bzoj千题计划289:bzoj 2707&colon; &lbrack;SDOI2012&rsqb;走迷宫

    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. &lbrack;BZOJ 4820&rsqb; &lbrack;SDOI2017&rsqb; 硬币游戏&lpar;高斯消元&plus;概率论&plus;字符串hash&rpar;

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

随机推荐

  1. Lrc2Srt字幕转换精灵

    最近喜欢下点英文的MV,可字幕太少了,可lrc文件却很丰富,写了一个转换精灵 下载地址:http://files.cnblogs.com/files/rovedog/Lrc2Srt.zip 需要.ne ...

  2. PO、VO、BO、DTO、POJO、DAO

    J2EE开发中大量的专业缩略语很是让人迷惑,尤其是跟一些高手讨论问题的时候,三分钟就被人家满口的专业术语喷晕了,PO VO BO DTO POJO DAO,一大堆的就来了(听过老罗对这种现象的批判的朋 ...

  3. Linux 容器技术史话:从 chroot 到未来

    Linux 容器是一个在单一 Linux 主机上提供多个隔离的 Linux 环境的操作系统级虚拟技术.不像虚拟机(VM),容器并不需要运行专用的访客(guest)操作系统.容器们共享宿主机的(host ...

  4. &lbrack;转&rsqb;10个学习Android开发的网站推荐

    本文转自:http://blog.csdn.net/i_lovefish/article/details/43950893 1. Android Developers 作为一个Android开发者,官 ...

  5. 第二百零五天 how can I 坚持

    身体无论什么时候都是最重要的.肝血管瘤,头一次听说,应该没什么大碍.父母年龄大了,我们也该尽快把自己的事情处理好,让他们放心了. 规律作息,合理饮食,多注意锻炼. 该怎么办.不能这拖下去. 好好规划下 ...

  6. DATAGUARD中手工处理日志v&dollar;archive&lowbar;GAP的方法

    从9i以后,oracle dataguard 备库一般都不需要手工处理丢失的日志,FAL自动会帮我们处理,下面通过个案例来讲下手工处理丢失的日志的方法: 1.在备库查询有哪些日志丢失,没应用到备库 S ...

  7. BZOJ 3196 二逼平衡树

    Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的 ...

  8. 并发工具箱 concurrent包的原理分析以及使用

    1.java.util.concurrent 包下的类分类图 locks部分:显式锁(互斥锁和速写锁)相关: atomic部分:原子变量类相关,是构建非阻塞算法的基础: executor部分:线程池相 ...

  9. Qt Creator插件Todo

     转载:http://techieliang.com/2017/12/502/   文章目录 1. 插件启动 2. 插件效果 3. 插件配置 4. 使用 码代码的过程往往并不是一气呵成,有时候需要记录 ...

  10. webstorm 介绍

    最新版2017 破解 注册时,在打开的License Activation窗口中选择“License server”,在输入框输入下面的网址: http://idea.iteblog.com/key. ...