Solution -「CF113D」Museum
Upd 2021.10.21 更改了状态定义。
记 \(S(u)\) 表示 \(u\) 结点的相邻结点的集合。
又记 \(p(u)\) 表示走到了 \(u\) 且下一步继续留在 \(u\) 结点的概率,那么下一步离开 \(u\) 结点的概率即为 \(1 - p(u)\)。
设 \(f(i, j)\) 表示 Petya 在 \(i\) 且 Vasya 在 \(j\) 这种状态的期望出现次数。
可知所有的形如 \(f(i, i)\) 的状态都是不能用于转移的,因为它们已经是末状态了。
因为钦定了末状态只出现一次,故可知末状态的期望出现次数即该状态的概率。
故有
\]
显然这个转移是有后效性的,无法用简单的递推做。故考虑高斯消元,将该式转换为我们熟悉的方程形式进行求解即可。
共有 \(n ^ 2\) 只方程,时间复杂度 \(O(n ^ 6)\)。
因为一开始处于初始状态,故初始状态期望出现次数自带 \(1\)。
#include <cstdio>
#include <vector>
using namespace std;
int Abs(int x) { return x < 0 ? -x : x; }
int Max(int x, int y) { return x > y ? x : y; }
int Min(int x, int y) { return x < y ? x : y; }
int read() {
int x = 0, k = 1;
char s = getchar();
while (s < '0' || s > '9') {
if (s == '-')
k = -1;
s = getchar();
}
while ('0' <= s && s <= '9') {
x = (x << 3) + (x << 1) + (s ^ 48);
s = getchar();
}
return x * k;
}
void write(int x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
void print(int x, char c) {
write(x);
putchar(c);
}
const int MAXN = 23 * 23 + 5;
struct Elimination {
bool free[MAXN];
int n, m, rk, opt;
double a[MAXN][MAXN], eps;
Elimination() { eps = 1e-15; }
Elimination(int N, int M) {
n = N;
m = M;
}
double Abs(double x) { return x < eps ? -x : x; }
void Swap(double &x, double &y) {
double t = x;
x = y;
y = t;
}
void clear() {
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) a[i][j] = 0;
}
void calc() {
int r = 1, c = 1;
for (; r <= n && c <= m; r++, c++) {
int pos = r;
for (int i = r + 1; i <= n; i++)
if (Abs(a[i][c]) > Abs(a[pos][c]))
pos = i;
if (Abs(a[pos][c]) < eps) {
r--;
continue;
}
if (pos != r)
for (int i = c; i <= m; i++) Swap(a[r][i], a[pos][i]);
double t;
for (int i = 1; i <= n; i++)
if (i != r && Abs(a[i][c]) > eps) {
t = a[i][c] / a[r][c];
for (int j = m; j >= c; j--) a[i][j] -= t * a[r][j];
}
}
rk = r;
}
};
int deg[MAXN];
double p[MAXN];
vector<int> mp[MAXN];
void Add_Edge(int u, int v) {
mp[u].push_back(v);
mp[v].push_back(u);
}
struct node {
int x, y;
node() {}
node(int X, int Y) {
x = X;
y = Y;
}
int Get(int n) { return (x - 1) * n + y; }
};
int main() {
int n = read(), m = read(), x = read(), y = read();
for (int i = 1, u, v; i <= m; i++) {
u = read(), v = read();
Add_Edge(u, v);
deg[u]++, deg[v]++;
}
for (int i = 1; i <= n; i++) scanf("%lf", &p[i]);
Elimination q;
q.n = n * n;
q.m = q.n + 1;
q.clear();
q.a[node(x, y).Get(n)][q.m] = -1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
int pos = node(i, j).Get(n);
q.a[pos][pos]--;
if (i != j)
q.a[pos][pos] += p[i] * p[j];
for (size_t k1 = 0; k1 < mp[i].size(); k1++)
for (size_t k2 = 0; k2 < mp[j].size(); k2++) {
int u = mp[i][k1], v = mp[j][k2];
if (u == v)
continue;
q.a[pos][node(u, v).Get(n)] += (1 - p[u]) * (1 - p[v]) / deg[u] / deg[v];
}
for (size_t k = 0; k < mp[i].size(); k++)
if (mp[i][k] != j)
q.a[pos][node(mp[i][k], j).Get(n)] += (1 - p[mp[i][k]]) / deg[mp[i][k]] * p[j];
for (size_t k = 0; k < mp[j].size(); k++)
if (mp[j][k] != i)
q.a[pos][node(i, mp[j][k]).Get(n)] += (1 - p[mp[j][k]]) / deg[mp[j][k]] * p[i];
}
q.calc();
for (int i = 1; i <= n; i++)
printf("%.9f\n", q.a[node(i, i).Get(n)][q.m] / q.a[node(i, i).Get(n)][node(i, i).Get(n)]);
return 0;
}
Solution -「CF113D」Museum的更多相关文章
- Solution -「构造」专练
记录全思路过程和正解分析.全思路过程很 navie,不过很下饭不是嘛.会持续更新的(应该). 「CF1521E」Nastia and a Beautiful Matrix Thought. 要把所有数 ...
- Solution -「原创」Destiny
题目背景 题目背景与题目描述无关.签到愉快. 「冷」 他半靠在床沿,一缕感伤在透亮的眼眸间荡漾. 冷见惆怅而四散逃去.经历嘈杂喧嚣,感官早已麻木.冷又见空洞而乘隙而入.从里向外,这不是感官的范畴. 他 ...
- Solution -「GLR-R2」教材运送
\(\mathcal{Description}\) Link. 给定一棵包含 \(n\) 个点,有点权和边权的树.设当前位置 \(s\)(初始时 \(s=1\)),每次在 \(n\) 个结点内 ...
- Solution -「WF2011」「BZOJ #3963」MachineWorks
\(\mathcal{Description}\) Link. 给定你初始拥有的钱数 \(C\) 以及 \(N\) 台机器的属性,第 \(i\) 台有属性 \((d_i,p_i,r_i,g_i ...
- Solution -「LOCAL」二进制的世界
\(\mathcal{Description}\) OurOJ. 给定序列 \(\{a_n\}\) 和一个二元运算 \(\operatorname{op}\in\{\operatorname{ ...
- Solution -「SHOI2016」「洛谷 P4336」黑暗前的幻想乡
\(\mathcal{Description}\) link. 有一个 \(n\) 个结点的无向图,给定 \(n-1\) 组边集,求从每组边集选出恰一条边最终构成树的方案树.对 \(10^9+ ...
- Solution -「LOCAL」大括号树
\(\mathcal{Description}\) OurTeam & OurOJ. 给定一棵 \(n\) 个顶点的树,每个顶点标有字符 ( 或 ).将从 \(u\) 到 \(v\) ...
- Solution -「ZJOI2012」「洛谷 P2597」灾难
\(\mathcal{Description}\) link. 给定一个捕食网络,对于每个物种,求其灭绝后有多少消费者失去所有食物来源.(一些名词与生物学的定义相同 w.) 原图结点数 \ ...
- Solution -「JSOI2008」「洛谷 P4208」最小生成树计数
\(\mathcal{Description}\) link. 给定带权简单无向图,求其最小生成树个数. 顶点数 \(n\le10^2\),边数 \(m\le10^3\),相同边权的边数不 ...
随机推荐
- 跨域原因及SpringBoot、Nginx跨域配置
目录 概述 简单请求 跨域解决方案 概述 SpringBoot跨域配置 Nginx跨域配置 概述 MDN文档 Cross-Origin Resource Sharing (CORS) 跨域的英文是Cr ...
- Barbican密钥管理器服务
Barbican服务介绍 Key Manager 服务 (barbican) 提供机密数据的安全存储.配置和管理.这包括密钥材料,例如对称密钥.非对称密钥.证书和原始二进制数据. Barbican 是 ...
- linux下nginx软件的学习
参考博客 1.nginx是什么 nginx是一个开源的,支持高性能,高并发的web服务和代理服务软件.它是开源的软件. nginx比它大哥apache性能改进许多,nginx占用的系统资源更少,支持更 ...
- 『忘了再学』Shell基础 — 15、环境变量(三)
目录 1.LANG语系变量介绍 2.如何查看Linux中支持的语系 3.查看当前系统的语系 4.总结 提示: 在Linux系统中,环境变量分为两种.一种是用户自定义的环境变量,另一种是系统自带的环境变 ...
- 流,用声明性的方式处理数据集 - 读《Java 8实战》
引入流 Stream API的代码 声明性 更简洁,更易读 可复合 更灵活 可并行 性能更好 流是什么? 它允许以声明方式处理数据集合 遍历数据集的高级迭代器 透明地并行处理 简短定义:从支持数据处理 ...
- 面试突击55:delete、drop、truncate有什么区别?
在 MySQL 中,删除的方法总共有 3 种:delete.truncate.drop,而三者的用法和使用场景又完全不同,接下来我们具体来看. 1.delete detele 可用于删除表的部分或所有 ...
- App上看到就忍不住点的小红点是如何实现的?
你有没有发现,我们解锁手机后桌面上App右上角总能看到一个小红点,这就是推送角标.推送角标指的是移动设备上App图标右上角的红色圆圈,圆圈内的白色数字表示未读消息数量.角标是一种比较轻的提醒方式,通过 ...
- c++ 关于二分的STL 详解
一.解释 以前遇到二分的题目都是手动实现二分,不得不说错误比较多,关于返回值,关于区间的左闭右开等很容易出错,最近做题发现直接使用STL中的二分函数方便快捷还不会出错,不过对于没有接触过的同学,二分函 ...
- 第6章 字符串(下)——C++字符串
6.5 C++ strings(C++字符串) C风格字符串常见错误:试图去访问数组范围以外的元素:没有使用函数strcpy( )来实现字符串之间的复制:没有使用函数strcmp( )来比较两个字符串 ...
- D3.JS结合Canvas实现直方图,散点图,等高线图,密度图
接触到D3.JS,感觉在图表方面实现的很好,于是深入了解了一下,想在项目中使用, 可是当看到DEMO时才发现,基本上所有的DEMO都是基于SVG,虽然D3.JS声称支持CANVAS,可并没有发现一例使 ...