[Luogu1119]采蘑菇
题目大意:
给你一个无向图,点i在时间t[i]之前是不存在的,有q组询问,问你时间为t时从x到y的最短路。
点的编号按出现的时间顺序给出,询问也按照时间顺序给出。
思路:
Floyd。
Floyd的本质思想就是一个动规,
由于你的点和询问都是按照时间顺序给出的,因此我们就可以只用枚举询问时间之前的点作为中转点k。
然后就是裸的Floyd。
1 #include<cstdio> 2 #include<cctype> 3 #include<algorithm> 4 inline int getint() { 5 register char ch; 6 while(!isdigit(ch=getchar())); 7 register int x=ch^'0'; 8 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 9 return x; 10 } 11 const int inf=0x7fffffff; 12 const int N=200; 13 int t[N],f[N][N]; 14 int main() { 15 const int n=getint(),m=getint(); 16 for(register int i=0;i<n;i++) { 17 t[i]=getint(); 18 } 19 for(register int i=0;i<n;i++) { 20 for(register int j=0;j<n;j++) { 21 if(i!=j) f[i][j]=inf; 22 } 23 } 24 for(register int i=0;i<m;i++) { 25 const int u=getint(),v=getint(),w=getint(); 26 f[u][v]=f[v][u]=w; 27 } 28 for(register int q=getint(),k=0;q;q--) { 29 const int u=getint(),v=getint(),time=getint(); 30 if(t[u]>time||t[v]>time) { 31 puts("-1"); 32 continue; 33 } 34 for(;t[k]<=time&&k<n;k++) { 35 for(register int i=0;i<n;i++) { 36 if(f[i][k]==inf) continue; 37 for(register int j=0;j<n;j++) { 38 if(f[k][j]==inf) continue; 39 f[i][j]=std::min(f[i][j],f[i][k]+f[k][j]); 40 } 41 } 42 } 43 printf("%d\n",f[u][v]==inf?-1:f[u][v]); 44 } 45 return 0; 46 }