题目背景
地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响。但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车。换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄。
题目描述
给出地区的村庄数,村庄编号从到,和所有条公路的长度,公路是双向的。并给出第个村庄重建完成的时间,你可以认为是同时开始重建并在第天重建完成,并且在当天即可通车。若为则说明地震未对此地区造成损坏,一开始就可以通车。之后有个询问,对于每个询问你要回答在第天,从村庄到村庄的最短路径长度为多少。如果无法找到从村庄到村庄的路径,经过若干个已重建完成的村庄,或者村庄或村庄在第天仍未重建完成 ,则需要返回。
输入输出格式
输入格式:
第一行包含两个正整数,表示了村庄的数目与公路的数量。
第二行包含个非负整数,表示了每个村庄重建完成的时间,数据保证了。
接下来行,每行个非负整数,为不超过的正整数,表示了有一条连接村庄与村庄的道路,长度为,保证,且对于任意一对村庄只会存在一条道路。
接下来一行也就是行包含一个正整数,表示个询问。
接下来行,每行个非负整数,询问在第天,从村庄到村庄的最短路径长度为多少,数据保证了是不下降的。
输出格式:
共行,对每一个询问输出对应的答案,即在第天,从村庄到村庄的最短路径长度为多少。如果在第天无法找到从村庄到村庄的路径,经过若干个已重建完成的村庄,或者村庄或村庄在第天仍未修复完成,则输出。
输入输出样例
输入样例#1:
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 -1 5 4 # 说明 对于的数据,有;
对于的数据,有,其中有20%20%的数据有且;
对于的数据,有;
对于的数据,有,,,所有输入数据涉及整数均不超过。
说明
本题基本上是Floyd的模版题,适合初学Floyd的OIer练习。
本题的重点在于并非在每一个时刻,每一个节点都可以到达,所以应枚举目前所有可以到达的节点k,并以k为中转点进行更新。
同时,因为出题人已经给数据排好了顺序,发现未建成时直接中断即可。
闲话少说,主要看代码注释。
#代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| #include<cstdio> #include<algorithm> using namespace std;
const int MAXN = 200 + 5; const int INF = 1e9;
int edge[MAXN][MAXN], times[MAXN]; int n, m, q;
void init() { for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { edge[i][j] = (i == j ? 0 : INF); } } }
void addEdge(int i, int j, int v) { edge[i][j] = edge[j][i] = v; }
void input() { scanf("%d%d", &n, &m); init(); for(int i = 0; i < n; i++) { scanf("%d", ×[i]); } for(int i = 0; i < m; i++) { int x, y, v; scanf("%d%d%d", &x, &y, &v); addEdge(x, y, v); } }
void update(int k) { for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { edge[i][j] = min(edge[i][j], edge[i][k] + edge[k][j]); } } }
void work() { int cur = 0; scanf("%d", &q); for(int i = 0; i < q; i++) { int x, y, t; scanf("%d%d%d", &x, &y, &t); while(times[cur] <= t && cur < n) { update(cur); cur++; } if(times[x] > t || times[y] > t || edge[x][y] == INF) { printf("-1\n"); } else { printf("%d\n", edge[x][y]); } } }
int main() { input(); work(); return 0; }
|