luoguP1119 灾后重建
Floyd算法深刻理解
最开始只允许经过1号顶点进行中转,接下来只允许经过1和2号顶点进行中转……允许经过1~n号所有顶点进行中转,求任意两点之间的最短路程。用一句话概括就是:从i号顶点到j号顶点只经过前k号点的最短路程。
因为给的时间是不下降的序列,所以肯定要从第一个村庄开始修路,这样用时间来判断,每个村庄是否做中转的点
#include <bits/stdc++.h>
using namespace std;
const int N = 210,M = N * (N - 1) / 2 + 10,INF = 0x3f3f3f3f;
int g[N][N],n,m,times[N];
void updata(int k) {
for(int i = 0;i < n; ++i)
for(int j = 0;j < n; ++j)
g[i][j] = min(g[i][j],g[i][k] + g[k][j]);
}
int main() {
cin >> n >> m;
for(int i = 0;i < n; ++i) cin >> times[i];
for(int i = 0;i < n; ++i)
for(int j = 0;j < n; ++j)
g[i][j] = (i == j ? 0 : INF);
for(int i = 0;i < m; ++i) {
int a,b,c;
cin >> a >> b >> c;
g[a][b] = g[b][a] = min(g[a][b],c);
}
int q,cur = 0;
cin >> q;
while(q --) {
int x,y,t;
cin >> x >> y >> t;
while(times[cur] <= t && cur < n) {
updata(cur);
cur ++;
}
if(times[x] > t || times[y] > t || g[x][y] == INF) cout << "-1\n";
else cout << g[x][y] << endl;
}
return 0;
}