灾后重建

Posted excellent-zzy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了灾后重建相关的知识,希望对你有一定的参考价值。

传送门:https://www.luogu.org/problemnew/show/P1119

  这道题其实就是floyd,大家肯定都会,这是一个看上去很简单的算法 ,整个算法一共只有五行,三重循环+一个判断就能求出图中任意两点之间的最短路径。

  背的话扫一眼就可以,然而这道题就是考大家是否明白floyd的原理。

  这个算法的主要思路,就是通过其他的点进行中转来求的两点之间的最短路。因为我们知道,两点之间有多条路,如果换一条路可以缩短距离的话,就更新最短距离。而它最本质的思想,就是用其他的点进行中转,从而达到求出最短路的目的。

  主要就是考虑中转的问题。两点之间可以由一个点作为中转点更新最短路径,也可以通过多个点更新最短路径。

while(t[k] <= z && k < n){
	for(int i = 0;i < n;i++)
		for(int j = 0;j < n;j++){
			dis[i][j] = min(dis[i][j],dis[i][k] + dis[k][j]);	
		}
	k++;
}        

  最开始只允许经过1号顶点进行中转,接下来只允许经过1和2号顶点进行中转……允许经过1~n号所有顶点进行中转,求任意两点之间的最短路程。就是:从i号顶点到j号顶点只经过前k号点的最短路程。

  所有的边全部给出,按照时间顺序更新每一个可用的点(即修建好村庄),对于每个时间点进行两点之间询问,求对于目前建设的所有村庄来说任意两点之间的最短路,就是Floyd算法中使用前k个节点更新最短路。

 

#define BB cout << "BreakPoint" << endl;
#define O(x) cout << #x << " " << x << endl;
#define O_(x) cout << #x << " " << x << "  ";
#define Msz(x) cout << "Sizeof " << #x << " " << sizeof(x)/1024/1024 << " MB" << endl;
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#define N 205
#define inf 0x7f7f77f
using namespace std;
inline int read() {
    int s = 0,w = 1;
    char ch = getchar();
    while(ch < ‘0‘ || ch > ‘9‘) {
        if(ch == ‘-‘)
            w = -1;
        ch = getchar();
    }
    while(ch >= ‘0‘ && ch <= ‘9‘) {
        s = s * 10 + ch - ‘0‘;
        ch = getchar();
    }
    return s * w;
}
int n,m,t[N],dis[N][N];
void init(){
	for(int i = 0;i < n;i++)
		for(int j = 0;j < n;j++){
			if(i == j) continue;
			dis[i][j] = inf;
		}
	return ;
}
void pre(){
	n = read(),m = read();
	for(int i = 0;i < n;i++)
		t[i] = read();
	init();
	for(int i = 1;i <= m;i++){
		int a,b,c;
		a = read(),b = read(),c = read();
		dis[a][b] = dis[b][a] = c;
		//O(dis[a][b])
	}
	return ;
}
int Q,k;
void solve(){
	Q = read();
	while(Q--){
		int x,y,z;
		x = read(),y = read(),z = read();
		while(t[k] <= z && k < n){
			for(int i = 0;i < n;i++)
				for(int j = 0;j < n;j++){
					dis[i][j] = min(dis[i][j],dis[i][k] + dis[k][j]);	
				}
			k++;
		}
		if(dis[x][y] == inf || t[x] > z || t[y] > z){
            printf("-1
");
            continue;
        }
        printf("%d
",dis[x][y]);
    }
    return ;
}
int main () {
    pre();
    solve();
    return 0;
}

 

  

 

以上是关于灾后重建的主要内容,如果未能解决你的问题,请参考以下文章

灾后重建

灾后重建

洛谷P1119 灾后重建(floyd)

题解灾后重建——(floyd)

P1119 灾后重建

灾后重建「解题报告」