CF1888E Time Travel 题解
这题可以使用经过改动的最短路 Dijkstra 算法。
建图的时候把时间标记也打上。考虑怎么进行这个 Dijkstra 算法:假设走到点 upper_bound 即可。
笔者在考场上
放代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n,t; cin>>n>>t;
vector<vector<pii> > g(n);
for(int i=1;i<=t;i++){
int m; cin>>m;
while(m--){
int u,v; cin>>u>>v;
g[--u].emplace_back(i,--v);
g[v].emplace_back(i,u);
}
} // 建图
int k; cin>>k;
vector<vector<int> > a(t+1);
for(int i=1;i<=k;i++){
int x; cin>>x;
a[x].emplace_back(i);
} // 存位置
vector<int> d(n,1e7); d[0]=0;
vector<bool> b(n);
priority_queue<pii,vector<pii>,greater<pii> > q;
q.emplace(0,0);
while(!q.empty()){
int u=q.top().second; q.pop();
if(b[u])continue; b[u]=true;
for(auto [w,i]:g[u]){
auto l=upper_bound(a[w].begin(),a[w].end(),d[u]);
if(l!=a[w].end()&&*l<d[i])q.emplace(d[i]=*l,i);
}
} // Dijkstra 过程
cout<<(d[n-1]==1e7?-1:d[n-1])<<endl;
return 0;
}