[题解]LuoGu1613:跑路

博客主要介绍了倍增法,它是一种加速个体信息合并的思想,合并两个相同长度区间信息的时间通常为O(logn),且需满足信息可合并的要求。还结合具体题目,说明可利用倍增法进行预处理,通过floyd算法求解最短路。

原题传送门

倍增法

说说我自己对倍增法的理解吧
这应该是一个思想,用来加速个体的信息合并

单个的个体,两个相同长度的区间的信息合并到一起,时间通常是 O ( l o g n ) O(logn) O(logn)

然后,倍增法应该得满足要求:信息可合并

就没了


本题,n<=50,肯定 f l o y d floyd floyd
所以我们需要知道那些点可以一步走到,接下来就是folyd的事情了

如何预处理是个问题,但是题目中机器的特点提醒我们可以用倍增
f [ i ] [ j ] [ l ] = 1 f[i][j][l]=1 f[i][j][l]=1表示点i到点j有一条长度为 2 l 2^l 2l的路径
这个可以用倍增预处理出来
w [ i ] [ j ] 表 示 i − &gt; j 最 短 路 w[i][j]表示i-&gt;j最短路 w[i][j]i>j,又当 w [ i ] [ j ] = 1 w[i][j]=1 w[i][j]=1需要满足存在 l l l,使得 f [ i ] [ j ] [ l ] = 1 f[i][j][l]=1 f[i][j][l]=1

Code:

#include <bits/stdc++.h>
#define maxn 110
using namespace std;
int w[maxn][maxn], f[maxn][maxn][maxn], n, m;

inline int read(){
	int s = 0, w = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
	for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
	return s * w;
}

int main(){
	n = read(), m = read();
	memset(w, 0x3f3f3f3f, sizeof(w));
	for (int i = 1; i <= m; ++i){
		int x = read(), y = read();
		f[x][y][0] = 1, w[x][y] = 1;
	}
	for (int l = 0; l <= 31; ++l)
		for (int k = 1; k <= n; ++k)
			for (int i = 1; i <= n; ++i)
				for (int j = 1; j <= n; ++j)
					if (f[i][k][l] && f[k][j][l]) f[i][j][l + 1] = 1, w[i][j] = 1;
	for (int k = 1; k <= n; ++k)
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= n; ++j)
				w[i][j] = min(w[i][j], w[i][k] + w[k][j]);
	printf("%d\n", w[1][n]);
	return 0;
}
请使用c++14 ## 题目背景 :::align{center} ![](https://cdn.luogu.com.cn/upload/image_hosting/9gqyhbfq.png) 迪拜蒂大巴拉沙漠中一场 15 公里赛的选手。 照片由 Joshua Bruns 拍摄,公有领域。 ::: ## 题目描述 你报名参加了 **Dune Dash**(沙丘冲刺),一项横穿沙漠的长比赛。一切都很顺利——除了在兴奋之中,你忘记启动 **StrideTrack**,那款记录你已距离的应用程序。现在你仅剩下官方检查点的位置,但却不知道你通过它们的先后顺序。 形式化地说,比赛包含 $N$ 个检查点,每个检查点由其在欧几里得平面上的坐标给出。你经过这些点的顺序未知,但赛事组织者设计赛道时保证选手无法偏离路线。具体而言,如果 $q_1, q_2, \dots, q_N$ 是比赛过程中正确的检查点访问顺序,那么对于所有满足 $i<j<k$ 的三元组,都有: $$ \text{dist}(q_i, q_k) \;>\; \max\bigl(\text{dist}(q_i, q_j),\ \text{dist}(q_j, q_k)\bigr) $$ 其中 $\text{dist}(p,q)$ 表示点 $p$ 与点 $q$ 的欧几里得距离。你的任务是确定比赛的总长度。 ![](https://cdn.luogu.com.cn/upload/image_hosting/bs9taqt8.png) 样例 2 的示意图。虚线表示实际赛道。 ## 输入格式 第一行包含整数 $N$($2 \le N \le 2 \cdot 10^5$)。 接下来的 $N$ 行中,每行包含两个整数 $x_i$ 与 $y_i$($-10^9 \le x_i, y_i \le 10^9$),表示检查点的坐标。 检查点的输入顺序不一定为实际经过顺序。 保证存在某种排列方式使得检查点满足上述距离条件。 输入中的 $N$ 个点均两两不同。 ## 输出格式 输出一个浮点数,即比赛总长度。 当你的答案的绝对误差或相对误差不超过 $10^{-6}$ 时,将被视为正确。 ## 输入输出样例 #1 ### 输入 #1 ``` 3 1 0 0 0 1 1 ``` ### 输出 #1 ``` 2.0 ``` ## 输入输出样例 #2 ### 输入 #2 ``` 10 -1 -7 -1 -11 0 -9 2 2 1 -2 2 -1 3 1 -1 -5 0 -3 -3 -11 ``` ### 输出 #2 ``` 17.186912597118443 ```
11-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值