题目链接:P1119
---------------------------------------
简化题意:
------------------------------------------
这是一道floyed的题。但是有所不同的是,这道题里的点是有时间限制的。
所以说我们在做floyed的时候,我们不能直接枚举所有中转点,而是按照时间来进行。
以及,有可能出现询问的时候两个点没有修好,我们还要判断这个。
而且在这道题里,询问的t是不下降的,这样我们就不用考虑数组的问题。我们在上一次询问时的更新,一定是合法的。
当然,因为询问和修复都是有时间的,所以说我们要在读完修复后,用一个堆去维护它。
------------------------------------------
读不明白?何不看看代码。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<queue> 5 #include<cstring> 6 using namespace std; 7 int n,m; 8 int ask; 9 int f; 10 int to; 11 int l; 12 int q; 13 int timee; 14 bool build[300]; 15 int flag; 16 struct vi{ 17 int num; 18 int t; 19 bool operator < (const vi &b) const{ 20 return t>b.t; 21 } 22 };//我们需要一个堆,而且要存修复的时间与村庄 23 priority_queue<vi> q2; 24 int map[300][300]; 25 int now; 26 void floyed(int k){//特别的更新 27 for(int i=0;i<n;++i){ 28 for(int j=0;j<n;++j){ 29 map[i][j]=min(map[i][j],map[i][k]+map[k][j]); 30 } 31 }//有0号点 32 } 33 int main(){ 34 memset(map,0x3f3f3f,sizeof(map));//初始化 35 cin>>n>>m; 36 for(int i=1;i<=n;++i){ 37 cin>>now; 38 q2.push((vi){ i-1,now});//有0号点 39 } 40 for(int i=1;i<=m;++i){ 41 cin>>f>>to>>l; 42 map[to][f]=map[f][to]=l;//存图 43 } 44 cin>>q; 45 for(int i=1;i<=q;++i){//因为说了时间不下降 46 cin>>f>>to>>timee; 47 { 48 while(q2.size()&&q2.top().t<=timee){//所以我们就可以在上一次询问的基础上直接用 49 //新修好的点去更新 50 //这样可以优化时间 51 vi noww=q2.top();//取出 52 floyed(noww.num); 53 build[noww.num]=1;//标记 54 q2.pop();//弹出 55 } 56 if(!build[f]||!build[to]){//如果有一个点没修好 57 cout<<-1<<endl; 58 continue; 59 60 } 61 else{ 62 if(map[f][to]>=0x3f3f3f){//好像写成==会有bug 63 cout<<-1<<endl;//反正这数据范围不可能超过 0x3f3f3f 64 } 65 else 66 { 67 cout<<map[f][to]<<endl;//直接输出 68 } 69 } 70 } 71 return 0; 72 } 73