Description
小
A
的工作不仅繁琐,更有苛刻的规定,要求小
Input
第一行两个整数
接下来m行每行两个数字
Output
一行一个数字,表示到公司的最少秒数。
Sample Input
4 4
1 1
1 2
2 3
3 4
Sample Output
1
About Sample
Hint
100%
的数据满足
n≤50,m≤10000
,最优解路径长度
≤maxlongint
Solution :
这道题题意说坑不坑的,想想也是,看来是自己有问题,题意是说用一次只能走到与你相距为
2k
的点,不能在中途停下。
好了,然我们想想到底给怎么做,首先,我们把我们需要的连边处理出来,就是一个的与它相距
2k
的点有连边,只要处理出来我们就可以跑最短路了,这是我们想到一个点与
2k
的点有连边是建立在
k−1
的基础上的,于是我们就有存在
edge[x][y][k−1]
和
edge[y][z][k−1]
, 这里的
edge
表示的是从
x
点可以经
Code :
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <ctime>
#include <map>
#include <vector>
using namespace std;
inline int read() {
int i = 0, f = 1;
char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') f = -1; ch = getchar();
}
while(isdigit(ch)) {
i = (i << 3) + (i << 1) + ch - '0'; ch = getchar();
}
return i * f;
}
const int MAXN = 50 + 5;
const int MAXM = 1e4 + 5;
int g[MAXN][MAXN][64], f[MAXN][MAXN];
int main() {
int n = read(), m = read();
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
f[i][j] = 100;
for(int i = 1; i <= m; ++i) {
int x = read(), y = read();
g[x][y][0] = 1;
f[x][y] = 1;
}
for(int t = 1; t <= 64; ++t)
for(int k = 1; k <= n; ++k)
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
if(g[i][k][t - 1] && g[k][j][t - 1]) {
g[i][j][t] = 1;
f[i][j] = 1;
}
for(int k = 1; k <= n; ++k)
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
printf("%d\n", f[1][n]);
}