灾后重建_洛谷1119_最短路

来源:互联网 发布:linux程序设计pdf下载 编辑:程序博客网 时间:2024/05/01 09:22

题目背景


B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响。但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车。换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄。

题目描述


给出B地区的村庄数N,村庄编号从0到N-1,和所有M条公路的长度,公路是双向的。并给出第i个村庄重建完成的时间t[i],你可以认为是同时开始重建并在第t[i]天重建完成,并且在当天即可通车。若t[i]为0则说明地震未对此地区造成损坏,一开始就可以通车。之后有Q个询问(x, y, t),对于每个询问你要回答在第t天,从村庄x到村庄y的最短路径长度为多少。如果无法找到从x村庄到y村庄的路径,经过若干个已重建完成的村庄,或者村庄x或村庄y在第t天仍未重建完成 ,则需要返回-1。

输入格式:


输入文件rebuild.in的第一行包含两个正整数N,M,表示了村庄的数目与公路的数量。

第二行包含N个非负整数t[0], t[1], …, t[N – 1],表示了每个村庄重建完成的时间,数据保证了t[0] ≤ t[1] ≤ … ≤ t[N – 1]。

接下来M行,每行3个非负整数i, j, w,w为不超过10000的正整数,表示了有一条连接村庄i与村庄j的道路,长度为w,保证i≠j,且对于任意一对村庄只会存在一条道路。

接下来一行也就是M+3行包含一个正整数Q,表示Q个询问。

接下来Q行,每行3个非负整数x, y, t,询问在第t天,从村庄x到村庄y的最短路径长度为多少,数据保证了t是不下降的。

输出格式:


输出文件rebuild.out包含Q行,对每一个询问(x, y, t)输出对应的答案,即在第t天,从村庄x到村庄y的最短路径长度为多少。如果在第t天无法找到从x村庄到y村庄的路径,经过若干个已重建完成的村庄,或者村庄x或村庄y在第t天仍未修复完成,则输出-1。

说明


对于30%的数据,有N≤50;

对于30%的数据,有t[i] = 0,其中有20%的数据有t[i] = 0且N>50;

对于50%的数据,有Q≤100;

对于100%的数据,有N≤200,M≤N*(N-1)/2,Q≤50000,所有输入数据涉及整数均不超过100000。

题解


n≤200很容易想到floyd吧
一条合法的最短路径必须满足起点、终点、中点都是合法的,那么枚举的时候判断一下就可以啦
还需要注意的是一个中点最多枚举1次,那么开一个桶就ok了

Code


#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <ctime>#include <iostream>#include <algorithm>#include <string>#include <vector>#include <deque>#include <list>#include <set>#include <stack>#include <queue>#include <numeric>#include <iomanip>#include <bitset>#include <sstream>#include <fstream>#define debug puts("-----")#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)#define drp(i, st, ed) for (int i = st; i >= ed; i -= 1)#define fill(x, t) memset(x, t, sizeof(x))#define min(x, y) x<y?x:y#define max(x, y) x>y?x:y#define PI (acos(-1.0))#define EPS (1e-8)#define INF (1<<30)#define ll long long#define db double#define ld long double#define N 201#define E N * 8 + 1#define MOD 100000007#define L 255using namespace std;int map[N][N], vis[N], t[N];inline int read(){    int x = 0, v = 1;    char ch = getchar();    while (ch < '0' || ch > '9'){        if (ch == '-'){            v = -1;        }        ch = getchar();    }    while (ch <= '9' && ch >= '0'){        x = (x << 1) + (x << 3) + ch - '0';        ch = getchar();    }    return x * v;}int main(void){    int n = read(), m = read();    fill(map, 63);    rep(i, 1, n){        t[i] = read();        map[i][i] = 0;    }    rep(i, 1, m){        int x = read() + 1, y = read() + 1, w = read() + 1;        map[x][y] = map[y][x] = w;    }    int opt = read();    while(opt --){        int st = read() + 1, ed = read() + 1, time = read();        rep(k, 1, n){            if (!vis[k] && t[k] <= time){                rep(i, 1, n){                    if (i ^ k){                        rep(j, 1, n){                            if (i ^ j && j ^ k && map[i][k] + map[k][j] < map[i][j]){                                map[i][j] = map[i][k] + map[k][j];                            }                        }                    }                }                vis[k] = 1;            }        }        if (t[st] <= time && t[ed] <= time && map[st][ed] != map[0][0]){            printf("%d\n", map[st][ed]);        }else{            printf("-1\n");        }    }    return 0;}
0 0
原创粉丝点击