1 P1119 灾后重建
problem
对于每个时间点,询问两点之间的路径(针对不同时间点各个点之间连通性不同)
solution
Floyd的本质是中转:
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(e[i][j]>e[i][k]+e[k][j])
e[i][j]=e[i][k]+e[k][j];
本题:按照时间顺序更新每一个点可用的点(即为修建好村庄),对于每个时间点询问,求对于目前建设的所有村庄来说任意两点之间的最短路。
与floyd中使用前k个节点更新最短路的思维一致。
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
#define N 205
int n,m;
int a[N],f[N][N];
void update(int k){
for(int i=0;i<n;i++) for(int j=0;j<n;j++)
if(f[i][j]>f[i][k]+f[j][k])
f[i][j]=f[i][k]+f[j][k];
return ;
}
int read(){
int op=1,ans=0;
char c;
c=getchar();
for(;(c<'0'||c>'9')&&c!='-';c=getchar());
if(c=='-') op=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar()) ans*=10,ans+=c^48;
return ans*op;
}
int main(){
n=read(),m=read();
//printf("%d %d",n,m);
for(int i=0;i<n;i++) a[i]=read();
for(int i=0;i<n;i++) for(int j=0;j<n;j++) f[i][j]=1e9;
for(int i=0;i<n;i++) f[i][i]=0;
int s1,s2,s3;
for(int i=0;i<m;i++) {
s1=read(),s2=read(),s3=read();
f[s1][s2]=f[s2][s1]=s3;
}
int q;q=read();
int now=0;
for(int i=1;i<=q;i++){
s1=read(),s2=read(),s3=read();
while(a[now]<=s3&&now<n){
update(now);//依次更新
now++;
}
if(a[s1]>s3||a[s2]>s3) printf("-1
");
else {
if(f[s1][s2]==1e9) printf("-1
");
else printf("%d
",f[s1][s2]);
}
}
return 0;
}
后记
感觉代码很好理解啊