CCF CSP 竞赛试题——行车路线(201712-4)

  • 从节点1到节点n的路,可以分为“宽路+窄路+宽路+窄路…”或者“窄路+宽路+窄路+宽路…”。不管怎样,窄路和宽路交替出现。
  • 将多段相连的短窄路放在一起考虑,在节点之间转移时,可以避免记录【到上一个节点时,最后走过的窄路的长度】。
  • 计算的时候要小心溢出,还要考虑有重边的情况。
#include <iostream>
#include <queue>
#include <climits>
using namespace std;

#define MAX_N 501

int wide[MAX_N][MAX_N]; // 各条宽路的长
int narr[MAX_N][MAX_N]; // 各条窄路的长 (经Floyd-Warshall算法转换成) 两两之间最短窄路距离
int n;                  // 节点数
int dist_wide[MAX_N];   // 节点1到各节点的最短距离,其中最后一段路为宽路
int dist_narr[MAX_N];   // 节点1到各节点的最短距离,其中最后一段路为窄路

int main() {
	int m;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= n; ++j)
			wide[i][j] = narr[i][j] = INT_MAX;
		dist_wide[i] = dist_narr[i] = INT_MAX;
	}
	while (m--) {
		int t, a, b, c;
		cin >> t >> a >> b >> c;
		if (t)
			narr[a][b] = narr[b][a] = min(narr[a][b], c); // 输入可能包含重边,一个小坑
		else
			wide[a][b] = wide[b][a] = min(wide[a][b], c); // 同上
	}
	for (int k = 1; k <= n; ++k)
		for (int i = 1; i <= n; ++i) if (narr[i][k] != INT_MAX)
			for (int j = 1; j <= n; ++j) if (narr[k][j] != INT_MAX)
				if (narr[i][j] > narr[i][k] + narr[k][j])
					narr[i][j] = narr[i][k] + narr[k][j];
	dist_narr[1] = dist_wide[1] = 0;
	queue<int> que;
	que.push(1);
	vector<bool> seen(n + 1); // 记录que里面有哪些节点
	seen[1] = true;
	while (!que.empty()) {
		int u = que.front();
		que.pop();
		seen[u] = false;
		for (int v = 1; v <= n; ++v) {
			bool flag = false;
			if (dist_narr[v] > dist_wide[u] + (long long)narr[u][v] * narr[u][v]) { // u经窄路到达v,要求到达u之前的一段路为宽路,小心溢出
				flag = true;
				dist_narr[v] = dist_wide[u] + narr[u][v] * narr[u][v];
			}
			if (dist_wide[v] > (long long)min(dist_narr[u], dist_wide[u]) + wide[u][v]) { // u经宽路到达v,到达u之前的一段路可以是宽路也可以是窄路
				flag = true;
				dist_wide[v] = min(dist_narr[u], dist_wide[u]) + wide[u][v];
			}
			if (flag && !seen[v]) { // 如果que里没有v,并且dist_narr[v]或者dist_wide[v]更新过,则将v加入que
				que.push(v);
				seen[v] = true;
			}
		}
	}
	cout << min(dist_wide[n], dist_narr[n]) << endl;
	return 0;
}
发布了33 篇原创文章 · 获赞 4 · 访问量 8747

猜你喜欢

转载自blog.csdn.net/Touchig/article/details/102755239