HDU 5636 Shortest Path(Floyd)

题目链接  HDU5636

n个点,其中编号相邻的两个点之间都有一条长度为1的边,然后除此之外还有3条长度为1的边。

m个询问,每次询问求两个点之前的最短路。

我们把这三条边的6个点两两算最短路,

然后询问的时候用这6个点的距离来更新答案就可以了。

(不过听说好像有更好的方法,先占个坑)

时间复杂度$O(216m)$

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)

typedef long long LL;

const LL mod = 1e9 + 7;

int T;
int n, m;
int a[10];
int b[10][10];
int d;
LL  ans, cnt;


int main(){

	scanf("%d", &T);
	while (T--){
		scanf("%d%d", &n, &m);
		rep(i, 1, 6) scanf("%d", a + i);
		ans = 0;
		cnt = 0;

		rep(i, 1, 6) rep(j, 1, 6) b[i][j] = abs(a[i] - a[j]);

		b[1][2] = b[2][1] = 1;
		b[3][4] = b[4][3] = 1;
		b[5][6] = b[6][5] = 1;

		rep(k, 1, 6) rep(i, 1, 6) rep(j, 1, 6)
			b[i][j] = min(b[i][j], b[i][k] + b[k][j]);
	

		for (; m--; ){
			scanf("%d%d", &a[7], &a[8]);
			d = abs(a[7] - a[8]);
			rep(i, 1, 6) rep(j, 1, 6)
				d = min(d, abs(a[i] - a[7]) + abs(a[j] - a[8]) + b[i][j]);

			(ans += (++cnt) * (LL)d) %= mod;
		}
		printf("%lld
", ans);
	}

	return 0;
}
原文地址:https://www.cnblogs.com/cxhscst2/p/7481713.html