// Submission: https://judge.yosupo.jp/submission/311622#include<iostream>#include<queue>#include<vector>constexprlonglonginf=0x3f3f3f3f3f3f3f3f;structEdge{intu,v,c;Edge(intu,intv,intc):u(u),v(v),c(c){}};intn,m,s,t,k;std::vector<std::vector<int>>gr,ig;// Graph and inverse graph.std::vector<Edge>edges;// Edges.std::priority_queue<std::pair<longlong,int>,std::vector<std::pair<longlong,int>>,std::greater<>>pq;std::vector<longlong>dist_t;// Calculate distances to the destination node t. (Dijkstra)voidcalc_distances_to_t(){dist_t.assign(n,inf);dist_t[t]=0;pq.emplace(dist_t[t],t);while(!pq.empty()){longlongdi=pq.top().first;intcur=pq.top().second;pq.pop();if(di>dist_t[cur])continue;for(autoe:ig[cur]){intnxt=edges[e].u;autodi_nxt=di+edges[e].c;if(di_nxt<dist_t[nxt]){dist_t[nxt]=di_nxt;pq.emplace(di_nxt,nxt);}}}}std::vector<longlong>ans;// Find the k shortest walk. (A* search)// Complexity: O(k * n * log(k * n)).voidfind_k_shortest_walks(){ans.assign(k,-1);std::vector<int>cnt(n);pq.emplace(dist_t[s],s);while(!pq.empty()){longlongcost=pq.top().first;intcur=pq.top().second;pq.pop();// Skip unreachable nodes.if(cost>=inf)continue;if(cur==t)ans[cnt[t]]=cost;++cnt[cur];// Terminate when the destination has been visited k times.if(cnt[t]>=k)break;// Expand the same node at most k times.if(cnt[cur]>k)continue;for(autoe:gr[cur]){intnxt=edges[e].v;autocost_nxt=cost-dist_t[cur]+edges[e].c+dist_t[nxt];pq.emplace(cost_nxt,nxt);}}}intmain(){// Input.std::cin>>n>>m>>s>>t>>k;gr.resize(n);ig.resize(n);edges.reserve(m);for(inti=0;i<m;++i){intu,v,c;std::cin>>u>>v>>c;edges.emplace_back(u,v,c);gr[u].push_back(i);ig[v].push_back(i);}// Calculate.calc_distances_to_t();find_k_shortest_walks();// Output.for(autox:ans)std::cout<<x<<'\n';return0;}
// Submission: https://judge.yosupo.jp/submission/311623#include<algorithm>#include<iostream>#include<queue>#include<random>#include<vector>std::mt19937_64rng(static_cast<std::mt19937_64::result_type>(time(nullptr)));constexprlonglonginf=0x3f3f3f3f3f3f3f3f;// Persistent Randomized Heap.structPersistentRandomizedHeap{staticconstexprintN=1e7;intid;std::vector<int>rt,lc,rc,to;std::vector<longlong>va;intnew_node(longlongcost,int_to){++id;va[id]=cost;to[id]=_to;returnid;}intcopy_node(intx){++id;lc[id]=lc[x];rc[id]=rc[x];va[id]=va[x];to[id]=to[x];returnid;}intmeld(intx,inty,std::mt19937_64::result_typerand){if(!x||!y)returnx|y;if(va[x]>va[y])std::swap(x,y);x=copy_node(x);if(rand&1)std::swap(lc[x],rc[x]);rc[x]=meld(rc[x],y,rand>>1);returnx;}PersistentRandomizedHeap():id(0),rt(N),lc(N),rc(N),to(N),va(N){}voidinsert(inti,longlongcost,int_to){rt[i]=meld(rt[i],new_node(cost,_to),rng());}voidmerge(inti,intj){rt[i]=meld(rt[i],rt[j],rng());}}heaps;structEdge{intu,v,c;Edge(intu,intv,intc):u(u),v(v),c(c){}};intn,m,s,t,k;std::vector<std::vector<int>>gr,ig;std::vector<Edge>edges;std::priority_queue<std::pair<longlong,int>,std::vector<std::pair<longlong,int>>,std::greater<>>pq;std::vector<longlong>dist_t;std::vector<int>out;// Calculate distances to the destination node t. (Dijkstra)// Record the optimal outgoing edges which form the shortest path tree T.voidcalc_distances_to_t(){dist_t.assign(n,inf);dist_t[t]=0;out.assign(n,-1);pq.emplace(dist_t[t],t);while(!pq.empty()){longlongdi=pq.top().first;intcur=pq.top().second;pq.pop();if(di>dist_t[cur])continue;for(autoe:ig[cur]){intnxt=edges[e].u;autodi_nxt=di+edges[e].c;if(di_nxt<dist_t[nxt]){dist_t[nxt]=di_nxt;out[nxt]=e;pq.emplace(di_nxt,nxt);}}}}// Construct sidetracks and propagate them through tree T.voidbuild_sidetracks(){// Insert all valid sidetracks into heaps.for(inti=0;i<m;++i){autoedge=edges[i];if(out[edge.u]!=i&&dist_t[edge.u]<inf&&dist_t[edge.v]<inf){heaps.insert(edge.u,edge.c+dist_t[edge.v]-dist_t[edge.u],edge.v);}}// Propagate sidetracks down the shortest path tree.std::queue<int>q;q.push(t);while(!q.empty()){autocur=q.front();q.pop();for(autoe:ig[cur]){autonxt=edges[e].u;if(out[nxt]==e){heaps.merge(nxt,cur);q.push(nxt);}}}}std::vector<longlong>ans;// Insert a non-empty heap into the priority queue.// Total cost is the heap top value adjusted by accumulated cost.voidinsert(intx,longlongcost){if(x)pq.emplace(cost+heaps.va[x],x);}// Find the k shortest paths in the sidetrack graph. (Dijkstra)// These correspond to the k shortest walks in the original graph.voidfind_k_shortest_walks(){intcnt=0;ans.assign(k,-1);if(dist_t[s]>=inf)return;ans[cnt++]=dist_t[s];insert(heaps.rt[s],dist_t[s]);while(!pq.empty()&&cnt<k){autocost=pq.top().first;intcur=pq.top().second;pq.pop();ans[cnt++]=cost;insert(heaps.lc[cur],cost-heaps.va[cur]);insert(heaps.rc[cur],cost-heaps.va[cur]);insert(heaps.rt[heaps.to[cur]],cost);}}intmain(){// Input.std::cin>>n>>m>>s>>t>>k;gr.resize(n);ig.resize(n);edges.reserve(m);for(inti=0;i<m;++i){intu,v,c;std::cin>>u>>v>>c;edges.emplace_back(u,v,c);gr[u].push_back(i);ig[v].push_back(i);}// Calculate.calc_distances_to_t();build_sidetracks();find_k_shortest_walks();// Output.for(autox:ans)std::cout<<x<<'\n';return0;}