[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 }

 

posted @ 2017-11-02 20:47  skylee03  阅读(116)  评论(0编辑  收藏  举报