BZOJ 2707: [SDOI2012]走迷宫 拓扑+高斯消元+期望概率dp+Tarjan
先Tarjan缩点 强连通分量里用高斯消元外面直接转移 注意删掉终点出边和拓扑
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#define N 10010
#define M 1000010
using namespace std;
typedef double D;
bool god=;
int n,m,s,e;
struct Went
{
int to,next;
}c[M],via[M],C[M];
int head[N],t,Head[N],T,adj[N],sz;
inline void Add(int x,int y)
{
c[++t].to=y;
c[t].next=head[x];
head[x]=t;
C[++T].to=x;
C[T].next=Head[y];
Head[y]=T;
}
inline void add(int x,int y)
{
via[++sz].to=y;
via[sz].next=adj[x];
adj[x]=sz;
}
int dfn[N],low[N],num,sum[N],stack[N],top,belong[N],id[N];
D a[][],prob[N],exp[N],ans[];
int topo[N],out[N];
bool in[N],can_get[N];
vector<int> team[N];
int Time;
inline int Min(int x,int y)
{
return x<y?x:y;
}
void tarjan(int x)
{
dfn[x]=low[x]=++Time;
in[x]=;
stack[++top]=x;
for(int i=head[x];i;i=c[i].next)
if(!dfn[c[i].to])
{
tarjan(c[i].to);
low[x]=Min(low[x],low[c[i].to]);
}
else if(in[c[i].to])
low[x]=Min(low[x],dfn[c[i].to]);
if(low[x]==dfn[x])
{
int j;
num++;
do
{
j=stack[top--];
in[j]=;
sum[num]++;
team[num].push_back(j);
id[j]=team[num].size();
belong[j]=num;
}while(j!=x);
}
}
int bang[N];
void buildnew()
{
for(int x=;x<=n;x++)
{
for(int i=head[x];i;i=c[i].next)
{
bang[x]++;
int y=c[i].to;
if(belong[x]==belong[y])continue;
add(belong[x],belong[y]);
}
}
}
int tool;
int indegree[N];
void light(int x)
{
can_get[x]=;
for(int i=adj[x];i;i=via[i].next)
{
out[x]++;
indegree[via[i].to]++;
if(!can_get[via[i].to])
light(via[i].to);
}
if(out[x]==)tool++;
}
queue<int> q;
int size;
void bfs()
{
q.push(belong[s]);
while(!q.empty())
{
int x=q.front();
q.pop();
topo[++size]=x;
for(int i=adj[x];i;i=via[i].next)
{
indegree[via[i].to]--;
if(indegree[via[i].to]==)
q.push(via[i].to);
}
}
}
void dfs(int x)
{
printf(" Now : %d\n",x);
for(int i=adj[x];i;i=via[i].next)
dfs(via[i].to);
}
void arrange()
{
buildnew();
light(belong[s]);
if(can_get[belong[e]]==)god=;
if(!god)return;
if(out[belong[e]]!=)god=;
if(!god)return;
if(tool!=)god=;
if(!god)return;
bfs();
}
void pre()
{
scanf("%d%d%d%d",&n,&m,&s,&e);
if(s==e)return;
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
if(x==e)continue;
Add(x,y);
}
for(int i=;i<=n;i++)
if(!dfn[i])
tarjan(i);
arrange();
if(!god)return;
}
inline D abs(D x)
{
return x<0.0?0.0-x:x;
}
inline void swap(D &x,D &y)
{
D z=x;
x=y;
y=z;
}
void gauss(int len)
{
for(int i=,k=;i<=len;i++,k++)
{
int temp=i;
D host=abs(a[i][k]);
for(int j=i+;j<=len;j++)
if(abs(a[j][k])>abs(a[temp][k]))
{
temp=j;
host=abs(a[j][k]);
}
if(temp!=i)
{
for(int j=k;j<=len+;j++)
swap(a[i][j],a[temp][j]);
}
for(int j=i+;j<=len;j++)
{
host=a[j][k]/a[i][k];
for(int l=k;l<=len+;l++)
a[j][l]-=a[i][l]*host;
}
}
for(int i=len;i>;i--)
{
for(int j=i+;j<=len;j++)
a[i][len+]-=a[i][j]*ans[j];
ans[i]=a[i][len+]/a[i][i];
} void work1()
{
prob[s]=1.0;
for(int i=;i<=size;i++)
{
int len=sum[topo[i]];
int x=topo[i];
for(int j=;j<=len+;j++)
for(int k=;k<=len+;k++)
a[j][k]=0.0;
for(int j=;j<len;j++)
{
int y=team[x][j];
a[j+][len+]-=prob[y];
a[j+][j+]+=-1.0;
for(int k=Head[y];k;k=C[k].next)
{
int z=C[k].to;
if(belong[z]!=x)continue;
a[j+][id[z]]+=1.0/bang[z];
}
}
gauss(len);
for(int j=;j<=len;j++)
prob[team[x][j-]]=ans[j];
for(int j=;j<len;j++)
{
int y=team[x][j];
for(int k=head[y];k;k=c[k].next)
{
int z=c[k].to;
if(belong[z]==x)continue;
prob[z]+=1.0/bang[y]*prob[y];
}
}
}
}
void work2()
{
for(int i=;i<=size;i++)
{
int len=sum[topo[i]];
int x=topo[i];
for(int j=;j<=len+;j++)
for(int k=;k<=len+;k++)
a[j][k]=0.0;
for(int j=;j<len;j++)
{
int y=team[x][j];
a[j+][len+]-=exp[y];
a[j+][j+]-=prob[y];
for(int k=Head[y];k;k=C[k].next)
{
int z=C[k].to;
if(belong[z]!=x)continue;
a[j+][id[z]]+=prob[z]*1.0/bang[z];
a[j+][len+]-=prob[z]*1.0/bang[z];
}
}
gauss(len);
for(int j=;j<=len;j++)
exp[team[x][j-]]=ans[j];
for(int j=;j<len;j++)
{
int y=team[x][j];
for(int k=head[y];k;k=c[k].next)
{
int z=c[k].to;
if(belong[z]==x)continue;
exp[z]+=(1.0/bang[y]*prob[y])*(exp[y]+1.0);
}
}
}
}
void work()
{
work1();
work2();
}
int main()
{
pre();
if(s==e)
{
printf("0.000");
return ;
}
if(!god)
{
printf("INF");
return ;
}
work();
printf("%.3lf",exp[e]);
return ;
}
BZOJ 2707: [SDOI2012]走迷宫 拓扑+高斯消元+期望概率dp+Tarjan的更多相关文章
- 洛谷 P6030 - [SDOI2012]走迷宫(高斯消元+SCC 缩点)
题面传送门 之所以写个题解是因为题解区大部分题解的做法都有 bug(u1s1 周六上午在讨论区里连发两个 hack 的是我,由于我被禁言才让 ycx 代发的) 首先碰到这种期望题,我们套路地设 \(d ...
- BZOJ 2707: [SDOI2012]走迷宫( tarjan + 高斯消元 )
数据范围太大不能直接高斯消元, tarjan缩点然后按拓扑逆序对每个强连通分量高斯消元就可以了. E(u) = 1 + Σ E(v) / degree(u) 对拍时发现网上2个程序的INF判断和我不一 ...
- BZOJ 2707: [SDOI2012]走迷宫 [高斯消元 scc缩点]
2707: [SDOI2012]走迷宫 题意:求s走到t期望步数,\(n \le 10^4\),保证\(|SCC| \le 100\) 求scc缩点,每个scc高斯消元,scc之间直接DP 注意每次清 ...
- bzoj 2707 [SDOI2012]走迷宫(SCC+高斯消元)
Description Morenan被困在了一个迷宫里.迷宫可以视为N个点M条边的有向图,其中Morenan处于起点S,迷宫的终点设为T.可惜的是,Morenan非常的脑小,他只会从一个点出发随机沿 ...
- BZOJ.2707.[SDOI2012]走迷宫(期望 Tarjan 高斯消元)
题目链接 一个点到达终点的期望步数 \(E_i=\sum_{(i,j)\in G}\frac{E_j+1}{out[i]}\),\(out[i]\)为点\(i\)的出度. 那么对于一个DAG可以直接在 ...
- 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 3640】JC的小苹果 (高斯消元,概率DP)
JC的小苹果 Submit: 432 Solved: 159 Description 让我们继续JC和DZY的故事. “你是我的小丫小苹果,怎么爱你都不嫌多!” “点亮我生命的火,火火火火火!” 话 ...
- First Knight UVALive - 4297(优化高斯消元解概率dp)
题意: 一个矩形区域被分成 m*n 个单元编号为 (1, 1)至 (m, n),左上为 (1, 1),右下为(m, n).给出P(k)i,j,其中 1 ≤ i ≤ m,1 ≤ j ≤ n,1 ≤ k ...
- BZOJ 2337: [HNOI2011]XOR和路径 [高斯消元 概率DP]
2337: [HNOI2011]XOR和路径 题意:一个边权无向连通图,每次等概率走向相连的点,求1到n的边权期望异或和 这道题和之前做过的高斯消元解方程组DP的题目不一样的是要求期望异或和,期望之间 ...
随机推荐
- 微信小程序scroll-viwe遇到的问题
1.当使用scroll-view的时候里面不可以使用某些标签 2.当使用scroll-view的时候会出现,子元素中滑动的时候会出现滚动的情况,我遇到的是因为view设置了高度和行高,一旦设置了这个, ...
- Django之模型---ORM简介
ORM ORM,是“对象-关系-映射”的简称,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因 ...
- Andy's First Dictionary(uva 10815) set用法
参考:https://www.cnblogs.com/yjlblog/p/6947747.html https://blog.csdn.net/hnust_taoshiqian/article/det ...
- android .9图制作
andorid .9 图,可用于适配各种屏幕.制作的时候,很简单. 在stadio 里面,把鼠标放到图片的边界,点一下.这时候,图片的边缘会有黑块. 然后把鼠标放到黑块上,发现可以拉伸区域了. 这个区 ...
- Cyclone IV器件的逻辑单元和逻辑阵列快
1. 逻辑单元 (LE) 在 Cyclone IV 器件结构中是最小的逻辑单位.LE 紧密且有效的提供了高级功能的逻辑使用.每个 LE 有以下特性:一个四口输入的查找表 (LUT),以实现四种变量的任 ...
- php-configure错误解决
configure: error: libjpeg.(a|so) not foundconfigure: error: libjpeg.(a|so) not foundln -sf libjpeg.s ...
- Scala学习笔记(四):从文件里读取文本行
第一个版本: import scala.io.Source if(args.length>0){ for(line<-Source.fromFile(args(0)).getLines) ...
- Qt Qwdget 汽车仪表知识点拆解4 另类进度条实现
先贴上效果图,注意,没有写逻辑,都是乱动的 注意看一下,右面的这两个进度条,有瑕疵,就是我没有把图片处理干净,这里犹豫我不知道这个具体的弧度,也没法绘制,就偷懒了 现在上面放一个UI,把两个进度条抠空 ...
- 安装arch系统时,把ubuntu的efi分区格式化
导致无法从grub进入ubuntu,之后我进入win10,把ubuntu的分区都删了. 再重启,只能进入黑色的grub界面,显示 grub>> 甚至无法进入win10.只能通过在开机时按F ...
- Python 3 学习笔记之——变量作用域、模块和包
1. 变量作用域 Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的.变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称.Python 的作用域一共 ...