解法
よくわからない。最初に乗る辺(バス停 1 から生えてるやつ) を決めて、それぞれの最短到着時刻をダイクストラで求める。
普通にやると遅くなるのは自明なので、あらかじめ辺を遅い順にソートしておくと、嬉しくなる(日本語難しいからソースコード(ry )。前の辺に乗った時よりも到着時刻が早くなっていれば、そのときの到着時刻と出発時刻をデキューに突っ込む。早くなってなければ、そのバスに乗っても意味がなさそうだから無かったことにする。
各クエリに答える時間はにぶたんでいい感じに求まる。
オーダーよくわかんない。
ソース
#include<bits/stdc++.h> using namespace std; const int INF = 1 << 30; struct Edge{ int to, st, gr; bool operator<(const Edge& e)const{ return st < e.st || (st == e.st && gr < e.gr); } }; typedef vector< vector< Edge > > Graph; typedef pair< int , int > Pi; Graph info; vector< int > min_time; int Dijkstra(int idx){ priority_queue< Pi, vector< Pi >, greater< Pi > > que; que.push( Pi( info[0][idx].gr, info[0][idx].to)); min_time[0] = info[0][idx].st; while(!que.empty()){ Pi p = que.top(); que.pop(); if(p.second + 1 == info.size()) return p.first; if(p.first > min_time[p.second]) continue; for(int i = 0; i < info[p.second].size(); ++i){ Edge& e = info[p.second][i]; if(e.st < p.first) break; //バスの出発時刻のほうが早い if(min_time[e.to] <= e.gr) continue; min_time[e.to] = e.gr; que.push( Pi( e.gr, e.to)); } } return -1; } int main(){ //A: 出発バス停, B: 到着バス停, X: 出発時刻, Y: 到着時刻 int N, M; int A, B, X, Y; int Q, L; scanf("%d %d", &N, &M); info.resize(N); min_time.resize(N, INF); for(int i = 0; i < M; ++i){ scanf("%d %d %d %d", &A, &B, &X, &Y); --A, --B; info[A].push_back( (Edge){ B, X, Y}); } for(int i = 0; i < N; ++i){ sort(info[i].rbegin(), info[i].rend()); } deque< Pi > good; int prev = INF; for(int i = 0; i < info[0].size(); ++i){ int accept = Dijkstra(i); //Pi(到着時刻, 出発時刻) if(accept == -1) continue; else if(prev > accept){ prev = accept; good.push_front( make_pair(prev, info[0][i].st)); } } good.push_front( make_pair( -1, -1)); scanf("%d", &Q); while(Q--){ scanf("%d", &L); deque< Pi >::iterator it = lower_bound( good.begin(), good.end(), make_pair( L + 1, -INF)); --it; //到着時刻直近で出発時刻が小さいもの printf("%d\n", it -> second); } }
0 件のコメント:
コメントを投稿