2707: [SDOI2012]走迷宫 tarjan+高斯消元解期望方程组
来源:互联网 发布:淘宝商品排名软件 编辑:程序博客网 时间:2024/04/28 04:48
SDOI2012啊,不错的一道题。
点数很多,我们不能直接高斯消元,而题目中提示了每个强连通分量的点数
先说一下无解的情况,如果有一个强连通分量到不了
考虑有解的情况,这就成了DAG上的期望DP问题,我们可以用
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#define N 10005#define M 1000005using namespace std;vector<int> V[N];double f[N],a[105][105];int n,m,S,T,tot,top,cnt,scc;int dfn[N],low[N],belong[N],du[N],rank[N],vis[N],stack[N],head[N];int list[M],next[M];bool inset[N];inline int read(){ int a=0,f=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();} return a*f;}inline void insert(int x,int y){ next[++cnt]=head[x]; head[x]=cnt; list[cnt]=y; du[x]++;}void tarjan(int x){ dfn[x]=low[x]=++tot; stack[++top]=x; inset[x]=true; for (int i=head[x];i;i=next[i]) if (!dfn[list[i]]) { tarjan(list[i]); low[x]=min(low[x],low[list[i]]); } else if (inset[list[i]]) low[x]=min(low[x],dfn[list[i]]); if (dfn[x]==low[x]) { int i=-1; scc++; while (i!=x) { i=stack[top--]; belong[i]=scc; rank[i]=V[scc].size(); V[scc].push_back(i); inset[i]=false; } }}void dfs(int x){ vis[x]=2; if (x==belong[T]) { vis[x]=1; return; } for (int i=0;i<V[x].size();i++) for (int j=head[V[x][i]];j;j=next[j]) if (belong[list[j]]!=x) { if (!vis[belong[list[j]]]) dfs(belong[list[j]]); if (vis[belong[list[j]]]==1) vis[x]=1; }}void get_ans(int x){ int n=V[x].size(); for (int i=0;i<n;i++) for (int j=head[V[x][i]];j;j=next[j]) if (belong[list[j]]!=x&&!vis[belong[list[j]]]) get_ans(belong[list[j]]); memset(a,0,sizeof(a)); for (int i=0;i<n;i++) { a[i][i]=1; if (V[x][i]==T) continue; a[i][V[x].size()]=1; for (int j=head[V[x][i]];j;j=next[j]) if (belong[list[j]]==x) a[i][rank[list[j]]]-=1.0/du[V[x][i]]; else a[i][V[x].size()]+=1.0/du[V[x][i]]*f[list[j]]; } for (int i=0;i<n;i++) { double t=a[i][i]; for (int j=0;j<=n;j++) a[i][j]/=t; for (int j=0;j<n;j++) if (j!=i) { double t=a[j][i]; for (int k=0;k<=n;k++) a[j][k]-=t*a[i][k]; } } for (int i=0;i<n;i++) f[V[x][i]]=a[i][n]; vis[x]=1;}int main(){ n=read(); m=read(); S=read(); T=read(); for (int i=1;i<=m;i++) { int u=read(),v=read(); insert(u,v); } for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i); memset(vis,0,sizeof(vis)); dfs(belong[S]); for (int i=1;i<=scc;i++) if (vis[i]==2) { puts("INF"); return 0; } memset(vis,0,sizeof(vis)); get_ans(belong[S]); printf("%.3lf\n",f[S]); return 0;}
0 0
- 2707: [SDOI2012]走迷宫 tarjan+高斯消元解期望方程组
- [BZOJ2707][SDOI2012]走迷宫(tarjan+概率期望+高斯消元)
- [BZOJ]2707: [SDOI2012]走迷宫 期望+高斯消元
- bzoj 2707: [SDOI2012]走迷宫 (高斯消元+概率期望+tarjan缩点+拓扑序)
- 【jzoj2758】【SDOI2012】【走迷宫】【期望】【高斯消元】
- bzoj 2707: [SDOI2012]走迷宫 期望dp+强连通分量+高斯消元
- [bzoj2707][SDOI2012]走迷宫
- BZOJ2707 [SDOI2012]走迷宫
- 【JZOJ2758】【SDOI2012】走迷宫(labyrinth)
- 3143: [Hnoi2013]游走 概率与期望 高斯消元解期望方程组
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 【2011集训队出题】Crash的数字表格
- ASP数组的应用
- 中文支持
- hdu 1863(畅通工程)
- Mybatis 初学
- 2707: [SDOI2012]走迷宫 tarjan+高斯消元解期望方程组
- 【留言板】 勾搭神犇 orz
- HDOJ 2005 第几天?(使用对象)
- 算法竞赛入门经典(第二版)-刘汝佳-第八章 高效算法设计 习题(18/28)
- Git常用命令集合
- UVa 11059 Maximum Product
- 蓝桥杯 手链样式 枚举
- hdu3746 Cyclic Nacklace--KMP
- Android_Fragment遇到BaiduMap