【Luogu P1119】灾后重建

链接

luogu P1119

题目描述

给出一个图,刚开始整个图都是封锁的,每个时间都会解锁部分点,只有一条路径上的两个点都被解锁了,这条路才可以通行,现在给出若干个询问,对于时间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]);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/LTH060226/article/details/115030688