D108 最短路 Floyd 算法 P1119 灾后重建
D108 最短路 Floyd 算法 P1119 灾后重建_哔哩哔哩_bilibili
无向图,如果一个点的点权 $>t$,第 $t$ 天时该点不可用。q 次询问:在第 $t$ 天,从点 x 到点 y 的最短路长度为多少。

思路
很明显是全源最短路,用 Floyd 算法,外层枚举插点时加上限制条件 a[k]<=t
点权 “数据保证了 $t_0≤t_1≤⋯≤t_{N−1}$”,询问 “数据保证了 t 是不下降的”,这样插点 k 是不下降的

相关板子:
D04【模板】最短路 Floyd 算法 - 董晓 - 博客园
// 最短路+点权限制 Floyd 算法 O(n^3+q) #include<bits/stdc++.h> #define N 205 using namespace std; int n,m,q,a[N],k=0; int d[N][N]; void Floyd(int t){ for(;a[k]<=t && k<n;k++) //枚举权值≤t的插点 for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(d[i][j]>d[i][k]+d[j][k]) d[i][j]=d[j][i]=d[i][k]+d[j][k]; } int main(){ cin>>n>>m; for(int i=0;i<n;i++)scanf("%d",a+i); for(int i=0;i<n;i++)for(int j=0;j<n;j++)d[i][j]=1e9; for(int i=0;i<n;i++)d[i][i]=0; for(int i=1,u,v,w; i<=m; i++){ scanf("%d%d%d",&u,&v,&w); d[u][v]=d[v][u]=w; } cin>>q; for(int i=1,u,v,t; i<=q; i++){ scanf("%d%d%d",&u,&v,&t); Floyd(t); //最短路 if(a[u]>t || a[v]>t) cout<<-1<<"\n"; //无插点情况 else{ if(d[u][v]==1e9) cout<<-1<<"\n"; else cout<<d[u][v]<<"\n"; } } }
浙公网安备 33010602011771号