• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
jacklee404
Never Stop!
博客园    首页    新随笔    联系   管理    订阅  订阅
牛站 类Floyd-dp + 矩阵快速幂

题目

牛站

思路

​ 首先题目没有给总共有多少点, 但是告诉我们边\(T \le 100\), 所以点的个数\(N \le 200\), 因此如果我们考虑\(bellman-ford\)魔改算法,复杂度在\(\Theta(NT) \le 1e8\), 所以我们先不考虑该算法, 考虑\(类Floyd\)算法复杂度在\(O(N^3)\)左右。

​ 先开个hash表进行离散化。

​ 我们设\(dp[k][i][j]\) 表示从\(i \rightarrow j\)恰好经过\(k\)条边的情况下的最短路径,那么状态转移方程类比floyd用中间点进行更新如下:

\[dp[k][i][j] = dp[k - x][i][m] + dp[x][m][j] \]

​ 但是这样转移的话,显然求出最后的\(dp[K][S][E]\) 的复杂度非常大, 我们寻找一些性质进行优化,考虑一条最短路径

\[S \rightarrow u_1 \rightarrow u_2 \rightarrow \dots \rightarrow E \]

​ 显然我们的\(状态函数\)满足这样一种规律, 即我们求出任意的\(dp[2][S][m] + dp[K - 2][m][E]\) 就是最终的答案,并不关心中间的路径问题,即求\(dp[k][S][E]\) 可以转化为 \(dp[maxbit(k)][S][m] + dp[k - maxbit(k)][m][E]\), 所以可以用倍增的思想来解决该问题, 并且运算满足结合律, 所以可以利用矩阵快速幂解决。

Code

#include <bits/stdc++.h>

using i64 = long long;

const int N = 210;

std::unordered_map<int, int> idx;

int n, k, m, S, E;

int g[N][N], res[N][N];

inline int get(int x) {
	if (idx.count(x)) {
		return idx[x];
	} return idx[x] = ++ n;
}

void mul(int c[][N], int a[][N], int b[][N]) {
	static int tmp[N][N];

	memset(tmp, 0x3f, sizeof tmp);

	for (int k = 1; k <= n; k ++)
		for (int i = 1; i <= n; i ++)
			for (int j = 1; j <= n; j ++)
				tmp[i][j] = std::min(tmp[i][j], a[i][k] + b[k][j]);

	memcpy(c, tmp, sizeof tmp);
}

void qmi() {
	memset(res, 0x3f, sizeof res);

	for (int i = 1; i <= n; i ++) res[i][i] = 0;

	while (k) {
		if (k & 1) mul(res, res, g);
		mul(g, g, g);
		k >>= 1;
	}
}

int main() {
	memset(g, 0x3f, sizeof g);

	std::cin >> k >> m >> S >> E;

	get(S);
	get(E);

	while (m --) {
		int a, b, c;

		std::cin >> a >> b >> c;

		int k1 = get(b), k2 = get(c);

		g[k1][k2] = g[k2][k1] = std::min(g[k1][k2], a);
	}

	// std::cout << n << "\n";

	qmi();

	std::cout << res[get(S)][get(E)];	
}
posted on 2023-05-05 20:56  Jack404  阅读(25)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3