Floyed Practice

一.入门级别

城市交通费
【问题描述】
有 n 个城市,编号 1~n。其中 i 号城市的繁华度为 pi。省内有 m 条可以双向同行的高速
公路,编号 1~m。编号为 j 的高速公路连接编号为 aj 和 bj 两个城市,经过高速公路的费用
是 wj。若从城市 x 出发到某城市 y,除了需要缴纳高速公路费用,还要缴纳“城市建设费”
(为从 x 城市到 y 城市所经过的所有城市中繁华度的最大值,包括 x 和 y 在内)。
现提出 q 个询问,每个询问给出一组 x 和 y,你需要回答从 x 出发到 y 城市,所需要的
最低交通费(高速公路费+城市建设费)是多少。
【输入】
第一行三个整数 n,m,q。
第二行 n 个整数,表示 p1~pn。
接下来 m 行中,每行 3 个正整数,第 j 行包含 Aj,Bj,Wj。
随后 Q 行每组两个正整数 x,y 表示一组询问。
【输出】
共 Q 行,为对 Q 个问题的回答:x 城市到 y 城市的最小交通费用。
【样例输入】

5 7 2
2 5 3 3 4
1 2 3
1 3 2
2 5 3
5 3 1
5 4 1
2 4 3
3 4 4
1 4
2 3

【样例输出】

8
9

【数据范围及约定】
n≤250,m≤20000,Q≤10000,Pi≤10000,Wj≤2000,保证任意两个城市可以互相到达。
【样例说明】
图中,代表城市的格子中第一个数字是城市编号,第二个红色数字是该城市的繁华度。
(1)从城市 1 到城市 4 的最小交通费用路线是:1 3 5 4;公路费是 2+1+1=4;城市建设费是
max{2,3,4,3}=4;总交通费用 4+4=8。
(2)从城市 2 到城市 3 的最小交通费用路线是:2 5 3;公路费是 3+1=4;城市建设费是
max{5,4,3}=5;总交通费用 4+5=9。
Code

#include<bits/stdc++.h>
using namespace std;

int n, m, q;
int cost[255][255];
int pros[255], ans[250][250], index[250];
int x, y, a, b, w;
bool cmp(int i1, int i2) {
	return pros[i1] < pros[i2];
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	for (int i = 0; i <= 255; i++) {
		for (int j = 0; j <= 255; j++) {
			cost[i][j] = 2000;
		}
	}
	cin >> n >> m >> q;
	for (int i = 1; i <= n; i++) {
		cin >> pros[i];
	}
	for (int i = 1; i <= m; i++) {
		cin >> a >> b >> w;
		cost[a][b] = min(w, cost[a][b]);
		cost[b][a] = min(w, cost[b][a]);
	}
	for (int i = 1; i <= n; i++) {
		cost[i][i] = 0;
		index[i] = i;
	}
	sort(index + 1, index + 1 + n, cmp);
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			ans[i][j] = cost[i][j] + max(pros[i], pros[j]);
		}
	}
	for (int k = 1; k <= n; k++) {
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				cost[i][j] = min(cost[i][j], cost[i][index[k]] + cost[index[k]][j]);
				ans[i][j] = min(ans[i][j], cost[i][j]+max(pros[i],max(pros[j],pros[index[k]])));
			}
		}
	}
	while (q--) {
		cin >> x >> y;
		cout << ans[x][y] << endl;
	}
	return 0;
}

二.电车

题目描述
在一个神奇的小镇上有着一个特别的电车网络,它由一些路口和轨道组成,每个路口都连接着若干个轨道,每个轨道都通向一个路口(不排除有的观光轨道转一圈后返回路口的可能)。在每个路口,都有一个开关决定着出去的轨道,每个开关都有一个默认的状态,每辆电车行驶到路口之后,只能从开关所指向的轨道出去,如果电车司机想走另一个轨道,他就必须下车切换开关的状态。

为了行驶向目标地点,电车司机不得不经常下车来切换开关,于是,他们想请你写一个程序,计算一辆从路口 AA 到路口 BB 最少需要下车切换几次开关。

在这里插入图片描述
输入输出样例

3 2 1
2 2 3
2 3 1
2 1 2
0

Code

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;

int n, a, b;
int k, num;
int ans[200][200];
const int INF = 0x3f3f3f3f;
void Floyed() {
	for (int k = 1; k <= n; k++) {
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				if(!(i==j||i==k||j==k))
					ans[i][j] = min(ans[i][j], ans[i][k] + ans[k][j]);
			}
		}
	}
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	memset(ans, INF, sizeof(ans));
	cin >> n >> a >> b;
	for (int i = 1; i <= n; i++) {
		ans[i][i] = 0;
	}
	for (int i = 1; i <= n; i++) {
		cin >> k;
		for (int j = 1; j <= k; j++) {
			cin >> num;
			if (j == 1) {
				ans[i][num] = 0;
			}
			else {
				ans[i][num] = 1;
			}
		}
	}
	Floyed();
	if (ans[a][b] == INF)cout << "-1" << endl;
	else {
		cout << ans[a][b] << endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值