CFR 257 1B. Jzzhu and Cities ( Dijkstra )
Problem - B - Codeforces
kmjpさんの解法を参考にしました。
kmjp.hatenablog.jp
trainのルートを全部あらかじめpqに入れて、もし一直線で着く方が速いならそれが先に出されて、その場でdisを更新しつつcountを上げる、そうでなければ普通にdijkstraする。
#include <bits/stdc++.h> using namespace std; const int MAXN = 1e5 + 5; const int MAXM = 3e5 + 5; const int MAXK = 1e5 + 5; const int MAXX = 1e9 + 9; const int MAXY = 1e9 + 9; typedef long long ll; typedef pair< ll, int > pli; int n, m, k; struct Edge{ int u, v, w; Edge( int _u = -1, int _v = -1, int _w = -1 ): u(_u), v(_v), w(_w){} } road[ MAXM << 1 ], train[ MAXK ]; vector< int > G[ MAXN ]; // will not include train ll dis[ MAXN ]; int dijk_vis[ MAXN ]; void solve(){ int used_train_cnt = 0; priority_queue< pli, vector< pli >, greater< pli > > pq; fill( dis, dis + MAXN, 1LL << 60 ); for( int i = 0; i < k; ++i ){ int v = train[ i ].v; int w = train[ i ].w; pq.push( pli( w, v ) ); } pq.push( pli( dis[ 1 ] = 0, 1 ) ); while( !pq.empty() ){ int u = pq.top().second; ll w = pq.top().first; pq.pop(); if( dijk_vis[ u ] ) continue; dijk_vis[ u ] = 1; if( dis[ u ] > w ){ ++used_train_cnt; dis[ u ] = w; } for( int vidx : G[ u ] ){ int v = road[ vidx ].v; int w = road[ vidx ].w; if( dis[ v ] > dis[ u ] + w ) dis[ v ] = dis[ u ] + w, pq.push( pli( dis[ v ], v ) ); } } printf("%d\n", k - used_train_cnt); } int main(){ scanf("%d%d%d", &n, &m, &k); for( int i = 0; i < m; ++i ){ int u, v, w; scanf("%d%d%d", &u, &v, &w); road[ i ] = Edge( u, v, w ); G[ u ].push_back( i ); road[ m + i ] = Edge( v, u, w ); G[ v ].push_back( m + i ); } for( int i = 0; i < k; ++i ){ int s, w; scanf("%d%d", &s, &w); train[ i ] = Edge( 1, s, w ); } solve(); return 0; }