洛谷P1119 灾后重建floyd的高级应用
题目链接:https://www.luogu.com.cn/problem/P1119
今天状态不是很好,心情是比较低落的,导致今天做题都不怎么在状态,看完这看那,结果啥都没弄好。
还是回归到刷题的快感上吧,把最短路和生成树的扩展问题刷一刷,毕竟,最小生成树和最短路好写,最短路双扩和次小就不太好弄了;
回归正题,这个题的意思是如果不能满足修路的日子或者是没修好就输出一,别的就输出最短路径。
实际上,看数据范围是可用floyd的,然后这个题就注重分析了:
庆幸的是,这个题还没有绝天人之路,因为给出的数据重建好的时间是排好序的,这就省去了我们手动排序的麻烦。
在者,抛去大部分问题来看,这个问题就是一个多源最短路问题,
还有一个比较重要的,我觉得这个题考的是对于floyd的理解程度,平心而论:
对于大部分算法我们都只背了模板,而就这个题而言,背模板你会发现是远远不够的,
所有的边全部给出,按照时间顺序更新每一个可用的点(即修建好村庄),对于每个时间点进行两点之间询问,求对于目前建设的所有村庄来说任意两点之间的最短路;
也就是说,我们要做的是在满足一定条件下,在询问在中进行floyd的算法实现,那问题就解决了。
Talk is cheap. Show me the code.
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int num=205; 4 const int INF=0x3f3f3f3f; 5 int p[num]; 6 int e[num][num]; 7 int n,m; 8 int now;//现在的中转点 9 int t; 10 void floyd(int k)//floyd更新每个k节点 11 { 12 for(register int i=0;i<n;i++) 13 { 14 for(register int j=0;j<n;j++) 15 { 16 if(e[i][j]>e[i][k]+e[k][j]) 17 e[i][j]=e[i][k]+e[k][j]; 18 } 19 } 20 } 21 int main() 22 { 23 std::ios::sync_with_stdio(false); 24 cin>>n>>m; 25 for(register int i=0;i<n;i++) 26 cin>>p[i]; 27 for(register int i=0;i<n;i++)//初始化 28 { 29 for(register int j=0;j<n;j++) 30 { 31 if(i==j) 32 { 33 e[i][j]=0; 34 } 35 else 36 { 37 e[i][j]=INF; 38 } 39 } 40 } 41 while(m--)// 42 { 43 int a,b,c; 44 cin>>a>>b>>c; 45 if(e[a][b]>c) 46 e[a][b]=e[b][a]=c; 47 } 48 cin>>t; 49 for(register int i=1;i<=t;i++) 50 { 51 int a,b,c; 52 cin>>a>>b>>c; 53 while(now<n&&p[now]<=c)//中转点要<n并且天数要满足条件 54 { 55 floyd(now);//中转点更新 56 now++;//下一个 57 } 58 if(p[a]>c||p[b]>c)//没修好 59 cout<<"-1"<<endl; 60 else 61 { 62 if(e[a][b]!=INF)//排除没有修的 63 cout<<e[a][b]<<endl; 64 else 65 cout<<"-1"<<endl; 66 } 67 } 68 return 0;; 69 }
本文来自博客园,作者:江上舟摇,转载请注明原文链接:https://www.cnblogs.com/LQS-blog/p/16204545.html