「专题训练」游走(BZOJ-3143)
题意与分析
定义走到每条边的期望为\(e_i\),一开始的想法是给定一个\(\large\sum_{i=1}^n e_i a_i\),求一个a的排列使得这个和最小。问题在于这样等于没对题目作分析,而且题目的难度没有被转化降低。于是(在高人指点下)我们想到,如果先求出\(e_i\),然后按照从小到大的顺序贪心的编号,问题就直接转化成求走到每个边的期望。
边的期望是一个新操作,但是其实不难:定义走到点的期望是\(f_i\),考虑一条边\((u, v)\),对于这条边而言,只有从u和从v才能走到这条边,那么它的期望就是\(\large e_i=\frac{f_u}{degree_u}+\frac{f_v}{degree_v}\)。于是问题又转化成走到各个点的期望。
如果这是个DAG,那么问题是一个dp(\(dp[j]\)表示从j到n的期望长度,\(dp[i] = \sum_{i\to j} \frac{dp[j]+1}{degree_i}\),具体问题见BZOJ-3036)。问题是这题并不是,场面有点尴尬。但是上面DAG的方程加起来共有n个,而我们要求n-1个解,这提示了我们用高斯消元解决这个问题。用高斯消元的话我们就把公式变形一下:
\]
其中\(p_{i,j}\)表示从j走到i的概率,对于第一个点该式子的右边还要加上一个1(因为一开始就在这个点上了,不妨思考下平凡的情况)。这样一来就可以用高斯消元解决这一题了。
问题的逐步转化是这一题的关键。
代码
#include <bits/stdc++.h>
using namespace std;
vector<pair<int, int>> edges;
vector<int> G[505];
double arr[505][505];
int main() {
int n, m;
while (cin >> n >> m) {
for (int i = 1, u, v; i <= m; ++i) {
cin >> u >> v;
if (u > v)
swap(v, u);
edges.push_back(make_pair(u, v));
G[u].push_back(v);
G[v].push_back(u);
}
memset(arr, 0, sizeof(arr));
for (int i = 1; i <= n; ++i)
arr[i][i] = -1.0;
arr[1][n + 1] = -1.0;
for (int i = 1; i < n; i++) {
for (int j = 0; j < G[i].size(); ++j)
arr[G[i][j]][i] += 1.0 / (int)G[i].size();
}
for (int i = 1; i <= n; ++i) {
int idx = i;
for (int j = i + 1; j <= n; ++j)
if (fabs(arr[j][i]) > fabs(arr[idx][i]))
idx = j;
assert(fabs(arr[idx][i]) > 1e-10);
if (idx != i)
for (int j = i; j <= n + 1; ++j)
swap(arr[i][j], arr[idx][j]);
for (int j = 1; j <= n; ++j)
if (i != j) {
double t = arr[j][i] / arr[i][i];
for (int k = i; k <= n + 1; ++k)
arr[j][k] -= arr[i][k] * t;
}
}
/*
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n + 1; ++j) {
cout << arr[i][j] << " ";
}
cout << endl;
}
*/
double e_node[505];
double e_edge[500 * 500 / 2 + 5];
memset(e_edge, 0, sizeof(e_edge));
memset(e_node, 0, sizeof(e_node));
for (int i = 1; i <= n; ++i) {
e_node[i] = arr[i][n + 1] / arr[i][i];
}
for (int i = 0; i < edges.size(); ++i) {
e_edge[i] += e_node[edges[i].first] / G[edges[i].first].size();
if (edges[i].second != n)
e_edge[i] += e_node[edges[i].second] / G[edges[i].second].size();
}
sort(e_edge, e_edge + m);
double ans = 0;
for (int i = 0; i < m; ++i)
ans += e_edge[i] * (m - i);
cout << fixed << setprecision(3) << ans << endl;
}
return 0;
}
「专题训练」游走(BZOJ-3143)的更多相关文章
- 游走 bzoj 3143
游走(2s 128MB)walk [问题描述] [输入格式] [输出格式] [样例输入] 3 3 2 3 1 2 1 3 [样例输出] 3.333 [样例说明] 题解: 主要算法:贪心:高斯消元: 题 ...
- 「HNOI 2013」游走
题目链接 戳我 \(Solution\) 首先申明几个变量: f[x]:到点x的概率, vis[x]:x点的度 dp[x][y]:(x,y)这条边的概率 number[x][y]:x这条边的编号 下面 ...
- 「专题训练」k-Tree(CodeForces Round #247 Div.2 C)
题意与分析(Codeforces-431C) 题意是这样的:给出K-Tree--一个无限增长的树,它的每个结点都恰有\(K\)个孩子,每个节点到它\(K\)个孩子的\(K\)条边的权重各为\(1,2, ...
- 「专题训练」Air Raid(HDU-1151)
题目 在一个城市里有\(n\)个地点和\(k\)条道路,道路是无环的(也就是说一定可以二分染色--回路长度为偶数0),现在伞兵需要去n个地点视察,只能沿着路的方向走,问最少需要多少伞兵. 分析 这是什 ...
- 「专题训练」Machine Schedule(HDU-1150)
题意 在一个工厂,有两台机器\(A, B\)生产产品.\(A\)机器有\(n\)种工作模式(模式\(0\),模式\(1\)--模式\(n-1\)).\(B\)机器有\(m\)种工作模式(模式\(0\) ...
- 「专题训练」Collecting Bugs(POJ-2096)
题意与分析 题意大致是这样的:给定一个\(n\times s\)的矩阵,每次可以随机的在这个矩阵内给一个格子染色(染过色的仍然可能被选中),问每一行和每一列都有格子被染色的次数的期望. 这题如果从概率 ...
- 「专题训练」Hard problem(Codeforces Round #367 Div. 2 C)
题意与分析 题意:给出\(n\)个字符串,可以反转任意串,反转每个串都有其对应的花费\(c_i\).经过操作后是否能满足字符串\(\forall i \in [1,n] \text{且} i \in ...
- 「专题训练」Boredom(CodeForces Round #260 Div.1 A)
题意(Codeforces-455A) 给你\(n\)个数,你每次可以选择删除去一个数\(x\)获得\(x\)分,但是所有为\(x+1\)和\(x-1\)的数都得删去.问最大获得分数. 分析 这是一条 ...
- 「HNOI2013」游走
「HNOI2013」游走 题目描述 一个无向连通图,顶点从 \(1\) 编号到 \(N\) ,边从 \(1\) 编号到 \(M\) .小 \(Z\) 在该图上进行随机游走,初始时小 \(Z\) 在 \ ...
随机推荐
- ORACLE数据库入门再在屋里坐会
一.数据库简介 数据库概述 数据库(database)是按照数据结构来组织,存储和管理数据的仓库,它产生与距今五十年前. 简单来说是本身可视为电子化的文件柜--存储电子文件的处所,用户可以对文件中的数 ...
- 【洛谷】【线段树】P3353 在你窗外闪耀的星星
[题目描述:] /* 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀 ...
- 使用阿里云的maven仓库
在maven的settings.xml文件里的mirrors节点,添加如下子节点: <mirror> <id>nexus-aliyun</id> <mirro ...
- 机器学习中的特征缩放(feature scaling)
参考:https://blog.csdn.net/iterate7/article/details/78881562 在运用一些机器学习算法的时候不可避免地要对数据进行特征缩放(feature sca ...
- Linux Shell常用技巧(四)
九. awk实用功能: 和sed一样,awk也是逐行扫描文件的,从第一行到最后一行,寻找匹配特定模板的行,并在这些行上运行“选择”动作.如果一个模板没有指定动作,这些匹配的行就被显示在屏幕上.如果一 ...
- linux系统分析工具之Blktrace
Blktrace简介: blktrace是一个针对Linux内核中块设备I/O层的跟踪工具,用来收集磁盘IO信息中当IO进行到块设备层(block层,所以叫blk trace)时的详细信息(如IO请求 ...
- springboot mybatis 后台框架平台 shiro 权限 集成代码生成器
1.代码生成器: [正反双向](单表.主表.明细表.树形表,快速开发利器)+快速表单构建器freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本.处理类.servic ...
- ios学习路线—Objective-C(属性修饰符)
readonly: 此标记说明属性是只读的,默认的标记是读写,如果你指定了只读,在@implementation中只需要一个读取器.或者如果你使用@synthesize关键字,也是有读取器方法被解析. ...
- js replace 全局替换
js 的replace 默认替换只替换第一个匹配的字符,如果字符串有超过两个以上的对应字符就无法进行替换,这时候就要进行一点操作,进行全部替换. <script language="j ...
- #leetcode刷题之路44-通配符匹配
给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配.'?' 可以匹配任何单个字符.'*' 可以匹配任意字符串(包括空字符串).两个字符串完全匹配才算匹配成 ...