题意

一个无向连通图,顶点从1编号到N,边从1编号到M。 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数。当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和。 现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小。(2<=N<=500)

分析

直接算边的期望会很大,考虑先算点的期望。

设 $E(i)$ 为经过第 $i$ 个点的期望次数,$D(i)$ 为 $i$ 的度数,设 $v$ 为与 $u$ 相连的点,则

$$E(u) = \sum_{v, v \neq n} \frac{E(v)}{D(v)}$$

从而,经过一条边 $(u, v)$ 的期望次数为

$$E(u, v)= \frac{E(u)}{D(u)} + \frac{E(v)}{D(v)}$$

有两点需要注意,结点1期望步数需要加1(可假设有结点0,以概率1转移到结点1);由于到结点 $n$ 就结束了,不要考虑来自 $n$ 的步数。

由于是无向连通图,不用考虑0和无穷大,方程组有唯一的解。

既然求出每条边的期望次数,当然是给次数大的分配小编号,次数小的分配大编号。

#include<bits/stdc++.h>
using namespace std; const int maxn = +;
typedef double Matrix[maxn][maxn]; //要求系数矩阵可逆
//这里的A是增广矩阵,即A[i][n] 是第i个方程右边的常数bi
//运行结束后A[i][n] 是第i个未知数的值
void gauss_elimination(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(r != i) for(j = ;j <= n;j++) swap(A[r][j], A[i][j]); //与第i+1~n行进行消元
for(k = i+; k < n;k++)
{
double f = A[k][i] / A[i][i];
for(int j = i;j <= n;j++) A[k][j] -= f * A[i][j]; //已经是阶梯型矩阵了,所以从i开始
}
} //回代过程
for(i = n-;i >= ;i--)
{
for(j = i+; j < n;j++)
A[i][n] -= A[j][n] * A[i][j];
A[i][n] /= A[i][i];
}
} void debug_print(Matrix A, int n)
{
for(int i = ;i < n;i++)
for(int j = ;j <= n;j++) printf("%f%c", A[i][j], j == n ? '\n' : ' ');
} int n, m;
vector<int>edges[maxn];
int d[maxn];
Matrix A;
vector<double>e; int main()
{
scanf("%d%d", &n, &m);
for(int i = ;i < m;i++)
{
int u, v;
scanf("%d%d", &u, &v);
u--; v--; //改成从0开始编号
edges[u].push_back(v);
edges[v].push_back(u);
d[u]++; d[v]++;
} //构造方程组
for(int i = ;i <n;i++)
{
A[i][i] = ;
for(int j = ;j <edges[i].size();j++)
if(edges[i][j] != n-) A[i][edges[i][j]] -= 1.0/d[edges[i][j]];
if(i == ) A[i][n] = ;
} //debug_print(A, n); gauss_elimination(A, n); for(int i = ;i < n;i++)
{
for(int j = ;j < edges[i].size();j++)
{
double tmp = ;
if(i != n-) tmp += A[i][n]/d[i];
if(edges[i][j] != n-) tmp += + A[edges[i][j]][n]/d[edges[i][j]]; //不是终点时
e.push_back(tmp);
}
} sort(e.begin(), e.end()); // for(int i = 0;i < e.size();i++) printf("%f ", e[i]);
// printf("\n"); double res = ;
for(int i = ;i < m;i++)
{
res += e[*i]*(m-i); //无向边重复了一次,所以隔一个取一个
}
printf("%.3f\n", res);
}

参考链接:https://www.luogu.org/problemnew/solution/P3232

P3232 [HNOI2013]游走——无向连通图&&高斯消元的更多相关文章

  1. BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元

    BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元 题意: 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机 ...

  2. BZOJ 3143: [Hnoi2013]游走 概率与期望+高斯消元

    Description 一个无向连通图,顶点从1编号到N,边从1编号到M.小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获 ...

  3. luoguP3232 [HNOI2013]游走 贪心 + 概率期望 + 高斯消元

    首先,题目中的无向简单连通图代表着没有自环,重边... 总分的期望 = 每条边的期望之和...................每条边的期望又可以拆成$u \to v$的期望和$v \to u$的期望 ...

  4. bzoj 3143 [Hnoi2013]游走(贪心,高斯消元,期望方程)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3143 [题意] 给定一个无向图,从1走到n,走过一条边得到的分数为边的标号,问一个边的 ...

  5. P3232 [HNOI2013]游走 解题报告

    P3232 [HNOI2013]游走 题目描述 一个无向连通图,顶点从\(1\)编号到\(N\),边从\(1\)编号到\(M\). 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概 ...

  6. 洛谷P3232 [HNOI2013]游走(高斯消元+期望)

    传送门 所以说我讨厌数学……期望不会高斯消元也不会……好不容易抄好了高斯消元板子被精度卡成琪露诺了…… 首先,我们先算出走每一条边的期望次数,那么为了最小化期望,就让大的期望次数乘上小编号 边的期望次 ...

  7. 题解 P3232 [HNOI2013]游走

    洛谷P3232[NOI2013]游走 题目描述 给定一个 n 个点 m 条边的无向连通图,顶点从 1 编号到 n,边从 1 编号到 m. 小 Z 在该图上进行随机游走,初始时小 Z 在 1 号顶点,每 ...

  8. 洛谷P3232[HNOI2013]游走

    有一个无向简单连通图,顶点从 \(1\) 编号到 \(n\),边从 \(1\) 编号到 \(m\) 小Z在该图上进行随机游走,初始时小Z在\(1\)号顶点,每一步小Z以相等的概率随机选 择当前顶点的某 ...

  9. [bzoj3143] [洛谷P3232] [HNOI2013] 游走

    Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点, ...

随机推荐

  1. [转帖]NSO到底是个什么样的公司?揭秘三叉戟0day的缔造者

    NSO到底是个什么样的公司?揭秘三叉戟0day的缔造者 dawner2016-09-07共248912人围观 ,发现 3 个不明物体其他安全报告 https://www.freebuf.com/art ...

  2. window 关机

    schtasks /create /tn "关机" /tr "shutdown /s" /sc once /st 20:30

  3. 递归实现全排列python

    python递归实现"abcd"字符串全排列 1.保持a不动,动bcd 2.保持b不动,动cd 3.保持c不动,动d def pailie(head="",st ...

  4. GIL全局解释锁,死锁,信号量,event事件,线程queue,TCP服务端实现并发

    一.GIL全局解释锁 在Cpython解释器才有GIL的概念,不是python的特点 在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势. 1.GIL介绍 ...

  5. Python列表添加元素

    Python列表添加元素 1.appent() 在列表尾部添加一个元素 >>>my_list.append("append方法") >>>my_ ...

  6. redis源码分析(六)--cluster集群同步

    Redis集群消息 作为支持集群模式的缓存系统,Redis集群中的各个节点需要定期地进行通信,以维持各个节点关于其它节点信息的实时性与一致性.如前一篇文章介绍的,Redis在专用的端口监听集群其它节点 ...

  7. 通过对比ASCII编码来理解Unicode编码

    Unicode是个规范,可以理解为一个索引表,世界上所有字符基本上在这个索引表中都能找到唯一一个数码与之对应,就像ASCII码表一样,也是一个规范,也可以看成是一个索引表,所有的英文字符都可以在这个索 ...

  8. VMware 网络介绍

       3.1 网卡介绍 如图所示,你的机器有两块网卡,一个是有线,一个是无线. 装完VM之后,会出现两块虚拟网卡,如图 VM有四种连接方式,我们着重介绍前三种    3.2 桥接 选择桥接模式,说明V ...

  9. Centos复制的系统无法获取IP地址

    本文主要是解决自己玩虚拟机时遇到的问题,网上查询了很多资料,最好综合多方的资料进行如下总结,如果无法解决您得问题,不要着急慢慢梳理总会解决的,加油~~~ 1.添加一块新的虚拟机的网卡2.删除rm -r ...

  10. 2019 昆仑万维java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.昆仑万维等公司offer,岗位是Java后端开发,因为发展原因最终选择去了昆仑万维,入职一年时间了,也成为了面 ...