思路是每个点用 map 维护某个时间点从这个点出去最早到终点是什么时候,然后维护一下单调性。最后把 1 处的 map 逆过来询问在里面二分。
然后交上去 T 掉了,n,m<2000 点也T。看了很久不知道为啥/yun。求大佬帮帮。
int n,m,q;
struct edge{
int u,v,a,b;
};
vector<edge>E;
inline bool cmp(edge A,edge B){
return A.a>B.a;
}
map<int,int>f[100300];
map<int,int>ANS;
inline void slv(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int u,v,a,b;
cin>>u>>v>>a>>b;
E.push_back({u,v,a,b});
}
sort(E.begin(),E.end(),cmp);
for(edge e:E){
if(e.v==n){
if(f[e.u].count(e.a))
f[e.u][e.a]=min(f[e.u][e.a],e.b);
else f[e.u][e.a]=e.b;
}
else {
auto it=f[e.v].lower_bound(e.b);
if(it!=f[e.v].end()){
if(f[e.u].count(e.a))
f[e.u][e.a]=min(f[e.u][e.a],p2(*it));
else f[e.u][e.a]=p2(*it);
}
}
auto it=f[e.u].lower_bound(e.a);
auto ip=it;
ip++;
if(ip!=f[e.u].end()&&p2(*ip)<=p2(*it))
f[e.u].erase(it);
else{
ip=it;
while(it!=f[e.u].begin()){
ip--;
if(p2(*ip)>=p2(*it))
f[e.u].erase(ip),ip=it=f[e.u].lower_bound(e.a);
else break;
}
}
}
for(auto e:f[1])
ANS[p2(e)]=p1(e);
cin>>q;
while(q--){
int lim=0;
cin>>lim;
auto it=ANS.upper_bound(lim);
if(it==ANS.begin())cout<<-1<<endl;
else it--,cout<<p2(*it)<<endl;
}
}