题意

给出一个程序控制流图,从每个结点出发到每个后继接结点的概率均相等。当执行完一个没有后继的结点后,整个程序终止。程序总是从编号为1的结点开始。你的任务是对于若干个查询结点,求出每个结点的期望执行次数。结点个数 $n < 10$.

分析

如果是有向无环图,可以直接解出递推关系,再采用记忆化搜索求解。

当这题可能有环,只能列出方程,用高斯消元解方程组。

设结点 $i$ 的出度为 $d_I$,期望的执行次数为 $x_i$。对于一个拥有三个前驱结点 $a, b, c$ 的结点 $i$,可以列出方程 $x_i = x_a / d_a + x_b / d_b + x_c / d_c$.

如果 $x_i$为无穷大或0,通过代数方法会出错的,所以我们结合实际意义考虑,

哪些结点期望执行无数次呢?就是那些无法到达终态的结点(即一直在非终态循环);

哪些结点期望执行次数为0次呢?就是那些从起点出发到不了的点。

我们可以先用Floyd求出传递闭包,先找到无穷大点和零点,

如果使用高斯-约当消元法可以避免这一预处理,当 $A[i][i] = A[i][n] = 0$ 时 $x_i=0$,而 $A[i][i] = 0$ 但 $A[i][n] > 0$ 时 $x_i$ 为正无穷大(这个结论看似显然

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std; const double eps = 1e-;
const int maxn = +;
typedef double Matrix[maxn][maxn]; //结果为A[i][n]/A[i][i]
void gauss_jordan(Matrix A, int n)
{
int i, j, k, r;
for(i = ;i < n;i++)
{
//选绝对值一行r并与第i行交换
r = i;
for(j = i+;j < n;j++)
if(fabs(A[j][i]) > fabs(A[r][i])) r = j;
if(fabs(A[r][i]) < eps) continue; //放弃这一行,直接处理下一行
if(r != i) for(j = ;j <= n;j++) swap(A[r][j], A[i][j]); //与除第i行外的其他行进行消元
for(k = ;k < n;k++) if(k != i)
for(j = n;j >= i;j--) A[k][j] -= A[k][i] / A[i][i] * A[i][j];
}
} Matrix A;
int n, d[maxn];
vector<int>pre[maxn];
int inf[maxn]; int main()
{
int kase = ;
while(scanf("%d", &n) == && n)
{
memset(d, , sizeof(d));
for(int i = ;i < n;i++) pre[i].clear(); int a, b;
while(scanf("%d%d", &a, &b) == && a)
{
a--; b--; //编号从0开始
d[a]++; //结点a的出度加1
pre[b].push_back(a);
} //构造方程组
memset(A, , sizeof(A));
for(int i = ;i < n;i++)
{
A[i][i] = ;
for(int j = ;j < pre[i].size();j++)
A[i][pre[i][j]] -= 1.0 / d[pre[i][j]];
if(i == ) A[i][n] = ;
} //解方程组,标记无穷变量
gauss_jordan(A, n);
memset(inf, , sizeof(inf));
for(int i = n-; i >= ;i--)
{
if(fabs(A[i][i]) < eps && fabs(A[i][n]) > eps) inf[i] = ; //直接解出来的无穷变量 for(int j = i+; j < n;j++) //和无穷变量扯上关系的变量也是无穷变量
if(fabs(A[i][j]) > eps && inf[j]) inf[i] = ;
} int q, u;
scanf("%d", &q);
printf("Case #%d:\n", ++kase);
while(q--)
{
scanf("%d", &u);
u--;
if(inf[u]) printf("infinity\n");
else printf("%.3f\n", fabs(A[u][u]) < eps ? 0.0 : A[u][n] / A[u][u]);
}
}
return ;
}

第一次在UVA官网交上题hh,题目链接

From:

《算法竞赛入门经典训练指南》——刘汝佳、陈锋著

UVa10828 Back to Kernighan-Ritchie——概率转移&&高斯消元法的更多相关文章

  1. 2019湖南省赛H题——概率转移&&逆矩阵

    题意 题目链接 Bobo有一个 $n+m$ 个节点的有向图,编号分别为 $1 \sim n$,他还有一个 $n$ 行 $n+m$ 列的矩阵 $P$. 如果在 $t$ 时刻他位于节点 $u(1 \leq ...

  2. UVA-10828 (概率期望+高斯消元)

    题意: 给个有向图,每个节点等概率转移到它的后继节点,现在问一些节点的期望访问次数; 思路: 对于一个点v,Ev=Ea/d[a]+Eb/d[b]+Ec/d[c];a,b,c是v的前驱节点; 然后按这个 ...

  3. bzoj 4008 亚瑟王 期望概率dp

    对于这种看起来就比较傻逼麻烦的题,最关键的就是想怎么巧妙的设置状态数组,使转移尽可能的简洁. 一开始我想的是f[i][j]表示到第j轮第i张牌还没有被选的概率,后来发现转移起来特别坑爹,还会有重的或漏 ...

  4. 2018.10.13 bzoj4008: [HNOI2015]亚瑟王(概率dp)

    传送门 马上2点考初赛了,心里有点小紧张. 做道概率dp压压惊吧. 话说这题最开始想错了. 最开始的方法是考虑f[i][j]f[i][j]f[i][j]表示第iii轮出牌为jjj的概率. 然后用第ii ...

  5. luoguP3239 [HNOI2015]亚瑟王 概率期望DP

    当初怎么想的来着.....又忘了...... 首先,总期望 = 每张卡片的期望之和 求期望,只要我们求出每张卡片被用掉的概率即可 如果直接上状态$f[i][j]$表示在第$i$轮中,第$j$张牌发动的 ...

  6. 【loj6191】「美团 CodeM 复赛」配对游戏 概率期望dp

    题目描述 n次向一个栈中加入0或1中随机1个,如果一次加入0时栈顶元素为1,则将这两个元素弹栈.问最终栈中元素个数的期望是多少. 输入 一行一个正整数 n . 输出 一行一个实数,表示期望剩下的人数, ...

  7. HDU - 1099 - Lottery - 概率dp

    http://acm.hdu.edu.cn/showproblem.php?pid=1099 最最简单的概率dp,完全是等概率转移. 设dp[i]为已有i张票,还需要抽几次才能集齐的期望. 那么dp[ ...

  8. HDU4576 Robot(概率)

    题意 抄袭自https://www.cnblogs.com/Paul-Guderian/p/7624039.html  多组输入n,m,l,r.表示在一个环上有n个格子.接下来输入m个w表示连续的一段 ...

  9. 基于机器学习的web异常检测——基于HMM的状态序列建模,将原始数据转化为状态机表示,然后求解概率判断异常与否

    基于机器学习的web异常检测 from: https://jaq.alibaba.com/community/art/show?articleid=746 Web防火墙是信息安全的第一道防线.随着网络 ...

随机推荐

  1. Win10最详细的优化设置 完美解决磁盘100%占用

    1.用360优化win10后开不了机的问题原因是禁用了三个服务:在360应用软件服务里dmwappushsvc.diagnsticsTrackingservice.coreMessaging这三个要开 ...

  2. Linux crontab 查看所有用户的crontab任务

    查看所有用户的crontab任务 - mlzhu007的专栏 - CSDN博客 https://blog.csdn.net/mlzhu007/article/details/81662091 以roo ...

  3. Java学习笔记二——正则表达式

    Java正则表达式 正则表达式的规则 “abc” 匹配字符串abc [abc] 匹配[]里任意一个字符 [a-z]: 匹配所有小写字母中的任意一个字符 [A-Z]: 匹配所有大写字母中的任意一个字符 ...

  4. 长乐国庆集训Day1

    T1 统计数字 题目 [题目描述] 设 S(N ) 表示 N 的各位数字之和,如 S(484) = 4+8+4 = 16, S(22) = 2+2 = 4. 如果一个正整数满足 S(x*x) = S( ...

  5. python 之 面向对象 (异常处理)

    7.15 异常处理 1.什么是异常 异常是错误发生的信号,程序一旦出错,如果程序中还没有相应的处理机制,那么该错误就会产生一个异常抛出来,程序的运行也随之终止 2.一个异常分为三部分: 异常的追踪信息 ...

  6. Oracle--(Hierarchical Queries)层级查询(用于部门层级等)

    原网址:https://www.cnblogs.com/guofeiji/p/5291486.html 如果表中包含层级数据,可以使用层级查询子句按层级顺序选择数据行,形成层级树,形式如下: 下面是层 ...

  7. John Lemon's Haunted Jaunt(鬼屋游戏笔记)

    1.使用Unity  2019.2.3 2.角色移动的控制脚本 3.后期处理组件PostProcessLayer  (类似给相机加上了一层滤镜) 4.制作简单的怪物AI系统,使用 NAvMeshAge ...

  8. 或与异或 [背包DP]

    也许更好的阅读体验 \(\mathcal{Description}\) 给定\(n\)和长度为\(n\)的数组\(a\) 问从\(a\)中选取任意个数使得其 异或起来的值 等于 或起来的值 的方案数 ...

  9. 1 matplotlib绘制折线图

    from matplotlib import pyplot as plt #设置图形大小 plt.figure(figsize=(20,8),dpi=80) plt.plot(x,y,color=&q ...

  10. Git查看文件制定行区间的提交记录

    git blame -L , /dir/file/file.php 这里查看file文件下6610至6613行的修改记录