結果
問題 | No.1442 I-wate Shortest Path Problem |
ユーザー | snow39 |
提出日時 | 2021-03-29 12:00:18 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 576 ms / 3,000 ms |
コード長 | 3,867 bytes |
コンパイル時間 | 1,759 ms |
コンパイル使用メモリ | 129,064 KB |
実行使用メモリ | 48,064 KB |
最終ジャッジ日時 | 2024-11-29 09:44:40 |
合計ジャッジ時間 | 10,393 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 8 ms
5,248 KB |
testcase_03 | AC | 42 ms
5,248 KB |
testcase_04 | AC | 8 ms
5,248 KB |
testcase_05 | AC | 5 ms
5,248 KB |
testcase_06 | AC | 42 ms
5,248 KB |
testcase_07 | AC | 6 ms
5,248 KB |
testcase_08 | AC | 38 ms
5,248 KB |
testcase_09 | AC | 13 ms
5,760 KB |
testcase_10 | AC | 45 ms
5,248 KB |
testcase_11 | AC | 44 ms
5,248 KB |
testcase_12 | AC | 399 ms
42,684 KB |
testcase_13 | AC | 210 ms
33,664 KB |
testcase_14 | AC | 307 ms
39,128 KB |
testcase_15 | AC | 279 ms
36,480 KB |
testcase_16 | AC | 384 ms
38,896 KB |
testcase_17 | AC | 569 ms
43,468 KB |
testcase_18 | AC | 567 ms
43,560 KB |
testcase_19 | AC | 443 ms
41,900 KB |
testcase_20 | AC | 552 ms
43,352 KB |
testcase_21 | AC | 576 ms
43,592 KB |
testcase_22 | AC | 224 ms
38,528 KB |
testcase_23 | AC | 428 ms
48,064 KB |
testcase_24 | AC | 187 ms
34,104 KB |
testcase_25 | AC | 397 ms
43,164 KB |
testcase_26 | AC | 181 ms
40,792 KB |
ソースコード
#include <iostream> #include <algorithm> #include <string> #include <vector> #include <cmath> #include <map> #include <queue> #include <iomanip> #include <set> #include <tuple> #define mkp make_pair #define mkt make_tuple #define rep(i,n) for(int i = 0; i < (n); ++i) #define all(v) v.begin(),v.end() using namespace std; typedef long long ll; const ll MOD=1e9+7; template<class T> void chmin(T &a,const T &b){if(a>b) a=b;} template<class T> void chmax(T &a,const T &b){if(a<b) a=b;} struct LowestCommonAncestor{ #define MAX_LOG_V 25 vector<vector<int>> g; int root; vector<int> parent[MAX_LOG_V]; vector<int> depth; LowestCommonAncestor(){} LowestCommonAncestor(int V,int root_):g(V),depth(V){ root=root_; for(int i=0;i<MAX_LOG_V;i++) parent[i].resize(V); } void initialize(int V,int root_){ g.resize(V); depth.resize(V,0); root=root_; for(int i=0;i<MAX_LOG_V;i++) parent[i].resize(V); } void add_edge(int u,int v){ g[u].push_back(v); g[v].push_back(u); } void dfs(int v,int p,int d){ parent[0][v]=p; depth[v]=d; for(int i=0;i<g[v].size();i++){ if(g[v][i]!=p) dfs(g[v][i],v,d+1); } } void build(int V){ dfs(root,-1,0); for(int k=0;k+1<MAX_LOG_V;k++){ for(int v=0;v<V;v++){ if(parent[k][v]<0) parent[k+1][v]=-1; else parent[k+1][v]=parent[k][parent[k][v]]; } } } int query(int u,int v){ if(depth[u]>depth[v]) swap(u,v); for(int k=0;k<MAX_LOG_V;k++){ if((depth[v]-depth[u])>>k&1){ v=parent[k][v]; } } if(u==v) return u; for(int k=MAX_LOG_V-1;k>=0;k--){ if(parent[k][u]!=parent[k][v]){ u=parent[k][u]; v=parent[k][v]; } } return parent[0][u]; } }; struct Edge{ int to; ll cost; Edge(){} Edge(int to,ll cost):to(to),cost(cost){} }; const ll INF=1e18; vector<ll> dijkstra(int st,vector<vector<Edge>> &g){ int N=g.size(); vector<ll> dist(N,INF); dist[st]=0; priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<pair<ll,int>>> PQ; PQ.push(mkp(0,st)); while(!PQ.empty()){ auto [d,now]=PQ.top(); PQ.pop(); if(dist[now]<d) continue; for(auto e:g[now]){ if(dist[e.to]>dist[now]+e.cost){ dist[e.to]=dist[now]+e.cost; PQ.push(mkp(dist[e.to],e.to)); } } } return dist; } int main(){ cin.tie(0); ios::sync_with_stdio(false); int N,K; cin>>N>>K; vector<vector<Edge>> g(N+K); vector<vector<Edge>> tree(N); LowestCommonAncestor lca(N,0); rep(i,N-1){ int a,b; ll c; cin>>a>>b>>c; a--;b--; g[a].push_back({b,c}); g[b].push_back({a,c}); tree[a].push_back({b,c}); tree[b].push_back({a,c}); lca.add_edge(a,b); } lca.build(N); vector<int> M(K); vector<ll> P(K); vector<vector<int>> X(K); rep(i,K){ cin>>M[i]>>P[i]; X[i].resize(M[i]); rep(j,M[i]){ cin>>X[i][j]; X[i][j]--; } } rep(i,K){ rep(j,M[i]){ g[N+i].push_back({X[i][j],0}); g[X[i][j]].push_back({N+i,P[i]}); } } vector<vector<ll>> dist(K); rep(i,K) dist[i]=dijkstra(N+i,g); vector<ll> tree_dist(N); {// tree auto dfs = [&](auto &&dfs,int now,int par,ll d)->void{ tree_dist[now]=d; for(auto e:tree[now]){ if(e.to==par) continue; dfs(dfs,e.to,now,d+e.cost); } }; dfs(dfs,0,-1,0); } int Q; cin>>Q; rep(q,Q){ int a,b; cin>>a>>b; a--;b--; ll ans=INF; int l=lca.query(a,b); chmin(ans,tree_dist[a]+tree_dist[b]-2*tree_dist[l]); rep(k,K) chmin(ans,dist[k][a]+dist[k][b]+P[k]); cout<<ans<<"\n"; } return 0; }