• 灾后重建


    传送门: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;
    }
    

      

     

  • 相关阅读:
    XSS
    web安全之sql注入
    12、API
    7、源与值(Source/Values)
    3、高级方法(Advanced Recipes)
    树莓派实现SIM868 ppp拨号上网
    【转】在树莓派上实现人脸识别
    树莓派raspbian安装matchbox-keyboard虚拟键盘
    python+树莓派实现IoT(物联网)数据上传到服务器
    python安装MySQLclient
  • 原文地址:https://www.cnblogs.com/excellent-zzy/p/10698331.html
Copyright © 2020-2023  润新知