Codeforces 1204C. Anna, Svyatoslav and Maps 最短路 Floyd

题意:给一个无权有向图,和一个行走序列,求出一个最短的序列,该序列需满足:

  1. 序列为行走序列的子序列,且起点及终点与行走序列相同
  2. 走该序列所经过的最短路之一为给定行走序列

思路:可以看出行走序列中一个点可以省略,当且仅当其前驱和后继之间的最短路必须经过该点;若前驱和后继不经过该点,表明有不经过该点的更短的路径,故必须将其加入答案序列,否则就不是给定序列的子序列。需要注意的是若前驱和后继为同一个点,则也必须加入答案序列(总不能停在一个点不走吧)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 100+5;
int n, m, g[maxn][maxn], p[1000005], res[1000005];
char s[maxn];
const int inf = 0x3f3f3f3f;
int main()
{
	cin >> n;
	memset(g, inf, sizeof(g));
	for (int i = 1; i <= n; i++) {
		scanf("%s", s+1);
		for (int j = 1; j <= n; j++) {
			if (s[j] == '1')
				g[i][j] = 1;
		}
	}
	for (int k = 1; k <= n; k++)
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				if (g[i][j] > g[i][k] + g[k][j])
					g[i][j] = g[i][k] + g[k][j];
	cin >> m;
	for (int i = 0; i < m; i++)
		cin >> p[i];
	int pre = 0, cnt = 0;
	res[cnt++] = p[0];
	for (int i = 1; i < m-1; i++) {
		if (g[p[pre]][p[i+1]] != g[p[pre]][p[i]] + g[p[i]][p[i+1]] || p[pre] == p[i+1]) {
			res[cnt++] = p[i];
			pre = i;
		}
	}
	res[cnt++] = p[m-1];
	printf("%d\n", cnt);
	for (int i = 0; i < cnt; i++)
		printf("%d ", res[i]);
	printf("\n");
 	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值