zoukankan      html  css  js  c++  java
  • 灾后重建

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

      

     

  • 相关阅读:
    jquery 序列化form表单
    nginx for windows 安装
    nodejs idea 创建项目 (一)
    spring 配置 shiro rememberMe
    idea 2018 解决 双击shift 弹出 search everywhere 搜索框的方法
    redis 在windows 集群
    spring IOC控制反转和DI依赖注入
    redis 的安装
    shiro 通过jdbc连接数据库
    handlebars的用法
  • 原文地址:https://www.cnblogs.com/excellent-zzy/p/10698331.html
Copyright © 2011-2022 走看看