链接
题目描述
给出一个图,刚开始整个图都是封锁的,每个时间都会解锁部分点,只有一条路径上的两个点都被解锁了,这条路才可以通行,现在给出若干个询问,对于时间t,问x到y的最短路是多少
样例输入
4 5
1 2 3 4
0 2 1
2 3 1
3 1 2
2 1 4
0 3 5
4
2 0 2
0 1 2
0 1 3
0 1 4
样例输出
-1
-1
5
4
思路
Floyd…考场上想到Floyd,但是自己手残打错了!
对,打错了!!!!!!
不愧是我
就是想到Floyd它是每次选择新点然后更新最短路,那么和我们这道题的性质就很相似,我们按照输出的时间不断加入新点,然后再更新最短路,输出即可
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int last, n, m, k, pp;
int t[1005], f[1005][1005];
void work(int now)
{
int e;
for(e = last; (t[e] <= now && e <= n); ++e)
{
for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j)
{
if (i == j || i == e || j == e) continue;
if((f[i][e] != pp) && (f[e][j] != pp))
f[i][j] = min(f[i][j], f[i][e] + f[e][j]);
}
}
last = e;
}
int main()
{
memset(f, 0x7f, sizeof(f));
pp = f[0][0];
scanf("%d%d", &n, &m);
for(int i = 0; i < n; ++i)
scanf("%d", &t[i]), f[i][i] = 0;
for(int i = 1; i <= m; ++i)
{
int x, y, w;
scanf("%d%d%d", &x, &y, &w);
f[x][y] = f[y][x] = w;
}
int Q;
scanf("%d", &Q);
int day = 0;
last = 0;
for(int i = 1; i <= Q; ++i)
{
int x, y, tt;
scanf("%d%d%d", &x, &y, &tt);
while(day <= tt) {
work(day);
day++;
}//不断更新最短路
if(t[x] >= day || t[y] >= day) printf("-1\n");
else {
if(f[x][y] == pp) printf("-1\n");
else printf("%d\n", f[x][y]);
}
}
}