Shortest Path HDU - 3631(floyd最短路)

题意

有n个点,m条有向边,q个询问,询问有两种操作,0和1,0操作输入一个x,将点x标记,如果x点在之前的操作已经被标记过了就输出 ERROR! At point x,否则标记这个点。1操作要求输入两个点x和y,如果x点没有被标记或者y点没有被标记,输出 ERROR! At path x to y ,否则输出x,y两点间的最短距离(求最短距离的时候只能根据已经被标记的点求),如果两点无法到达,输出No such path,否则输出最短距离。格式要注意,两个测试例子之间要输出一个空格。

思路

根据floyd求最短路,每次标记一个点x的时候,就根据x更新一次最短距离。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAX_N = 310;
const int MAX_M = 100010;
const int inf = 0x3f3f3f3f;
int Map[MAX_N][MAX_N];
int n, m, q;
int vis[MAX_N];
void floyd(int x) {
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			Map[i][j] = min(Map[i][j], Map[i][x] + Map[x][j]);
		}
	}
}
int main() {
	int k = 0;
	while (scanf("%d%d%d", &n, &m, &q) != EOF) {
		if (n == 0 && m == 0 && q == 0)break;
		k++;
		memset(vis, -1, sizeof vis);
		memset(Map, inf, sizeof Map);
		for (int i = 1; i <= n; i++)Map[i][i] = 0;
		for (int i = 1; i <= m; i++) {
			int x, y, z;
			scanf("%d%d%d", &x, &y, &z);
			x++, y++;
			Map[x][y] = min(Map[x][y], z);
		}
		if (k != 1)
			printf("\n");
		printf("Case %d:\n", k);
		for (int i = 1; i <= q; i++) {
			int opt, x, y;
			scanf("%d", &opt);
			if (opt == 0) {
				scanf("%d", &x);
				x++;
				if (vis[x] == 0) {
					printf("ERROR! At point %d\n", --x);
				}
				else {
					vis[x] = 0;
					floyd(x);
				}
			}
			else if (opt == 1) {
				scanf("%d%d", &x, &y);
				x++, y++;
				if (vis[x] == -1 || vis[y] == -1) {
					printf("ERROR! At path %d to %d\n", --x, --y);
				}
				else if (Map[x][y] == inf) {
					printf("No such path\n");
				}
				else {
					printf("%d\n", Map[x][y]);
				}
			}
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值