灾后重建
题目大意:题目信息量太大,请自行浏览:https://www.luogu.org/problemnew/show/P1119
多组询问,数据范围小,还是floyd。。。
不过这一次还出现了有一些不能走的点,不能走也就罢了,过两天居然又能走了?!
这都是些啥啊。。。
好了,不扯别的,还是看题:
注意题目中的条件限制!这是莫大的提示!
第二行包含N个非负整数t0,t1,…,tN−1,表示了每个村庄重建完成的时间,数据保证了t0≤t1≤…≤tN−1
接下来Q行,每行3个非负整数x,y,t,询问在第t天,从村庄x到村庄y的最短路径长度为多少,数据保证了t是不下降的。
根据这个,我们取消了可持久化(炸空间)的可能!也就是说,我们可以边操作边输出!我们考虑一下枚举天数:
首先,对于不能到达的情况,我们判断给出的两个点是否有到目前没有修好的就行
那么对于最短距离呢?
还是继续挖掘floyd的价值,我们枚举的k代表中间接口,如果我们不把不能走的点作为k,那么在目前这一天就对于其他能走的点没有影响
你可能会说:不对啊,那他的最短路被更新了啊
但是,能不能到达已经判断完毕,那么我们只要保证它不影响别人就行了
时间复杂度:O(n^3)
最后,附上本题代码:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 using namespace std; 7 //Debug Yufenglin 8 #define dej printf("Running\n"); 9 #define dep1(x) cout<<#x<<"="<<x<<endl; 10 #define dep2(x,y) cout<<#x<<"="<<x<<' '<<#y<<"="<<y<<endl; 11 #define dep3(x,y,z) cout<<#x<<"="<<x<<' '<<#y<<"="<<y<<' '<<#z<<"="<<z<<endl; 12 13 //Standfor Yufenglin 14 #define LL long long 15 #define LB long double 16 #define reg register 17 #define il inline 18 #define maxn 200 19 #define maxm 1005 20 21 int n,m,q,k; 22 int f[maxn+5][maxn+5],t[maxn+5]; 23 24 int main() 25 { 26 scanf("%d%d",&n,&m); 27 memset(f,0x3f,sizeof(f)); 28 for(int i=0; i<n; i++) 29 { 30 scanf("%d",&t[i]); 31 f[i][i]=0; 32 } 33 for(int i=1; i<=m; i++) 34 { 35 int x,y,z; 36 scanf("%d%d%d",&x,&y,&z); 37 f[x][y]=z,f[y][x]=z; 38 } 39 scanf("%d",&q); 40 for(int i=1; i<=q; i++) 41 { 42 int x,y,z; 43 scanf("%d%d%d",&x,&y,&z); 44 while(t[k]<=z&&k<n) 45 { 46 for(int i=0; i<n; i++) 47 { 48 for(int j=0; j<n; j++) 49 { 50 f[i][j]=min(f[i][j],f[i][k]+f[k][j]); 51 } 52 } 53 k++; 54 } 55 if(x>=k||y>=k) printf("-1\n"); 56 else printf("%d\n",f[x][y]); 57 } 58 return 0; 59 }