L3-007 天梯地图

#include <iostream>
#include <vector>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;

vector<vector<int>> len, tim;
vector<int> ans_tim, ans_len;
int n, m, s, e, v1, v2, one_way, l, t;
void input(vector<int>& ans, vector<int>& pre) {
	int a = e;
	while (a != s) {
		ans.push_back(a);
		a = pre[a];
	}
	ans.push_back(a);
	reverse(ans.begin(), ans.end());
	return;
}

void update(int k, vector<int>& dis, vector<vector<int>>& arr, vector<int>& pre, vector<int>& route, vector<int>& node_num, int node, int j) {
	dis[j] = dis[node] + arr[node][j];
	pre[j] = node;
	if (k) route[j] = route[node] + len[node][j];
	node_num[j] = node_num[node] + 1;
	return;
}
void dijkstra(int k, vector<vector<int>>& arr) {
	vector<int> dis(n, INF), vis(n, 0), pre(n, s), node_num(n, INF), route(n, INF);
	dis[s] = 0, node_num[s] = 0, route[s] = 0;
	for (int i = 0; i < n; i++) {
		int node = -1;
		for (int j = 0; j < n; j++) {
			if (vis[j]) continue;
			if (node == -1 || dis[node] > dis[j]) node = j;
		}
		vis[node] = 1;
		for (int j = 0; j < n; j++) {
			if (vis[j]) continue;
			if (dis[j] > dis[node] + arr[node][j]) {
				update(k, dis, arr, pre, route, node_num, node, j);
			}
			else if (dis[j] == dis[node] + arr[node][j]) {
				if (k) {
					if (route[node] + len[node][j] == route[j] && node_num[node] + 1 < node_num[j]) {
						update(k, dis, arr, pre, route, node_num, node, j);
					}
					else if (route[node] + len[node][j] < route[j]) {
						update(k, dis, arr, pre, route, node_num, node, j);
					}
				}
				else {
					if (node_num[node] + len[node][j] < node_num[j]) {
						update(k, dis, arr, pre, route, node_num, node, j);
					}
				}
			}
		}
	}
	if (k) input(ans_tim, pre);
	else input(ans_len, pre);
	return;
}
int get_sum(vector<int>& ans, vector<vector<int>>& arr) {
	int sum = 0;
	for (int i = 0; i < ans.size() - 1; i++) {
		sum += arr[ans[i]][ans[i + 1]];
	}
	return sum;
}

void output(vector<int>& ans) {
	int f = 0;
	for (auto x : ans) {
		if (f) cout << " => ";
		cout << x, f = 1;
	}
	return;
}
int main() {
	cin >> n >> m;
	tim.resize(n, vector<int>(n, INF)), len.resize(n, vector<int>(n, INF));
	while (m--) {
		cin >> v1 >> v2 >> one_way >> l >> t;
		len[v1][v2] = l, tim[v1][v2] = t;
		if (!one_way) len[v2][v1] = l, tim[v2][v1] = t;
	}
	cin >> s >> e;

	dijkstra(0, len), dijkstra(1, tim);
	if (ans_tim == ans_len) {
		cout << "Time = " << get_sum(ans_tim, tim) << "; Distance = " << get_sum(ans_len, len) << ": ";
		output(ans_tim);
	}
	else {
		cout << "Time = " << get_sum(ans_tim, tim) << ": "; 
		output(ans_tim);
		cout << endl;
		cout << "Distance = " << get_sum(ans_len, len) << ": "; 
		output(ans_len);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云儿乱飘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值