没有题面。
首先最短路判断一下有没有输出 -1 的情况。
然后把握答案可以二分求解的特点,那就很容易解决了。
令边中最大的年代为 maxx
那么就在[1,maxx]中进行二分求解,枚举年代mid,跑一遍最短路,不走年代<=mid的边,然后判断dis[n]是否>=T,如果>=说明mid可能偏大,否则mid可能偏小。
怎么优化?
把所有边的年代存下来,sort一次,然后在这些数据里面二分(mid只能是出现过的年代)。
优化你的最短路算法,例如SPFA的LLL优化与SLF优化
二分暴力求解即可。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 template<class T> inline void read(T &_a){ 6 int _ch=getchar();_a=0; 7 while(_ch<'0' || _ch>'9')_ch=getchar(); 8 while(_ch>='0' && _ch<='9'){_a=(_a<<1)+(_a<<3)+_ch-'0';_ch=getchar();} 9 } 10 11 const int maxn=20001,maxm=100001; 12 int n,m,T,egcnt,head[maxn],q[maxn],dis2[maxn],dis[maxn],tail,h,maxx; 13 bool ins[maxn],vis[maxn]; 14 struct edge{ 15 int next,to,dis,year; 16 }w[maxm<<1]; 17 18 inline void addedge(int from,int to,int dis,int year) 19 { 20 w[++egcnt].dis=dis; 21 w[egcnt].to=to; 22 w[egcnt].year=year; 23 w[egcnt].next=head[from]; 24 maxx=max(maxx,year); 25 head[from]=egcnt; 26 } 27 28 inline void spfa(int y){ 29 memset(dis,0x7f,sizeof(dis)); 30 dis[1]=0; q[1]=1; h=0; tail=1; 31 while(h!=tail) 32 { 33 h=h%20000+1; 34 int now=q[h]; 35 ins[now]=false; 36 for (register int i=head[now];i;i=w[i].next) 37 if(w[i].year>y){ 38 if(dis[w[i].to]>dis[now]+w[i].dis) 39 { 40 dis[w[i].to]=dis[now]+w[i].dis; 41 if(!ins[w[i].to]) 42 { 43 ins[w[i].to]=true; 44 tail=tail%20000+1; 45 q[tail]=w[i].to; 46 } 47 } 48 } 49 } 50 } 51 52 int main() 53 { 54 read(n); read(m); read(T); 55 for (register int i=1,s,t,l,y;i<=m;++i) read(s),read(t),read(l),read(y),addedge(s,t,l,y); 56 spfa(0); 57 if(dis[n]>=T) { printf("-1 %d",dis[n]); return 0; } 58 int l=1,r=maxx; 59 while(l<=r) 60 { 61 memset(vis,0,sizeof(vis)); 62 int mid=l+r>>1; 63 spfa(mid); 64 if(dis[n]<T) l=mid+1; 65 else r=mid-1; 66 } 67 printf("%d",r+1); 68 return 0; 69 }