题意

给出一个程序控制流图,从每个结点出发到每个后继接结点的概率均相等。当执行完一个没有后继的结点后,整个程序终止。程序总是从编号为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. C++中const限定符

    const基础 C++中的const,用于定义一个常量,这个常量的值不能被修改.因为const对象一旦创建就不能修改,所以const对象必须初始化.const常量特征仅仅在执行改变其本身的操作时才会发 ...

  2. 带小伙伴手写 golang context

    前言 - context 源码 可以先了解官方 context.go 轮廓. 这里捎带保存一份当前 context 版本备份. // Copyright 2014 The Go Authors. Al ...

  3. 单点logi,n

    using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; u ...

  4. aria2 https

    https://github.com/aria2/aria2/issues/361 ... and also make sure that aria2 was built with HTTPS sup ...

  5. canvas教程(一) 简介

    什么是 canvas 按例是要介绍一下 canvas 的,在没有 canvas 之前,我们为了网页的效果,很多情况下是使用了图片来实现,不过用图片就需要加载,而且图片的体积也是一个问题,所以在 htm ...

  6. Oracle队列实现

    Oracle队列实现 -- 核心技术点:for update 创建测试表 create table t ( id       number primary key, processed_flag va ...

  7. scrapy文件管道

    安装scrapy pip install scrapy 新建项目 (python36) E:\www>scrapy startproject fileDownload New Scrapy pr ...

  8. JS 小工具 MYSQL WHERE IN条件 去掉换行符(列转行)

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  9. Android笔记(七十五) Android中的图片压缩

    这几天在做图记的时候遇第一次遇到了OOM,好激动~~ 追究原因,是因为在ListView中加载的图片太大造成的,因为我使用的都是手机相机直接拍摄的照片,图片都比较大,所以在加载的时候会出现内存溢出,那 ...

  10. 基于GDI显示png图像

    intro 先前基于GDI已经能够显示BITMAP图像:windows下控制台程序实现窗口显示 ,其中BMP图像是使用LoadImage()这一Win32 API函数来做的.考虑到LoadImage( ...