結果
| 問題 |
No.1442 I-wate Shortest Path Problem
|
| コンテスト | |
| ユーザー |
beet
|
| 提出日時 | 2021-03-26 22:30:08 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 612 ms / 3,000 ms |
| コード長 | 4,162 bytes |
| コンパイル時間 | 2,641 ms |
| コンパイル使用メモリ | 219,268 KB |
| 最終ジャッジ日時 | 2025-01-19 23:03:14 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 25 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using Int = long long;
const char newl = '\n';
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
template<typename T> void drop(const T &x){cout<<x<<endl;exit(0);}
template<typename T=Int>
vector<T> read(size_t n){
vector<T> ts(n);
for(size_t i=0;i<n;i++) cin>>ts[i];
return ts;
}
template<typename T>
struct Dijkstra{
struct Edge{
Int to;
T cost;
Edge(Int to,T cost):to(to),cost(cost){}
bool operator<(const Edge &o)const{return cost>o.cost;}
};
vector< vector<Edge> > G;
vector<T> ds;
vector<Int> bs;
Dijkstra(Int n):G(n){}
void add_edge(Int u,Int v,T c){
G[u].emplace_back(v,c);
}
void build(Int s){
Int n=G.size();
ds.assign(n,numeric_limits<T>::max());
bs.assign(n,-1);
priority_queue<Edge> pq;
ds[s]=0;
pq.emplace(s,ds[s]);
while(!pq.empty()){
auto p=pq.top();pq.pop();
Int v=p.to;
if(ds[v]<p.cost) continue;
for(auto e:G[v]){
if(ds[e.to]>ds[v]+e.cost){
ds[e.to]=ds[v]+e.cost;
bs[e.to]=v;
pq.emplace(e.to,ds[e.to]);
}
}
}
}
T operator[](Int k){return ds[k];}
vector<Int> restore(Int to){
vector<Int> res;
if(bs[to]<0) return res;
while(~to) res.emplace_back(to),to=bs[to];
reverse(res.begin(),res.end());
return res;
}
};
struct LowestCommonAncestor{
Int h;
vector< vector<Int> > G,par;
vector<Int> dep;
LowestCommonAncestor(Int n):G(n),dep(n){
h=1;
while((1<<h)<=n) h++;
par.assign(h,vector<Int>(n,-1));
}
void add_edge(Int u,Int v){
G[u].emplace_back(v);
G[v].emplace_back(u);
}
void dfs(Int v,Int p,Int d){
par[0][v]=p;
dep[v]=d;
for(Int u:G[v])
if(u!=p) dfs(u,v,d+1);
}
void build(Int r=0){
Int n=G.size();
dfs(r,-1,0);
for(Int k=0;k+1<h;k++)
for(Int v=0;v<n;v++)
if(~par[k][v])
par[k+1][v]=par[k][par[k][v]];
}
Int lca(Int u,Int v){
if(dep[u]>dep[v]) swap(u,v);
for(Int k=0;k<h;k++)
if((dep[v]-dep[u])>>k&1)
v=par[k][v];
if(u==v) return u;
for(Int k=h-1;k>=0;k--)
if(par[k][u]!=par[k][v])
u=par[k][u],v=par[k][v];
return par[0][u];
}
Int distance(Int u,Int v){
return dep[u]+dep[v]-dep[lca(u,v)]*2;
}
};
template<typename F>
struct FixPoint : F{
FixPoint(F&& f):F(forward<F>(f)){}
template<typename... Args>
decltype(auto) operator()(Args&&... args) const{
return F::operator()(*this,forward<Args>(args)...);
}
};
template<typename F>
inline decltype(auto) MFP(F&& f){
return FixPoint<F>{forward<F>(f)};
}
//INSERT ABOVE HERE
signed main(){
cin.tie(0);
ios::sync_with_stdio(0);
Int n,k;
cin>>n>>k;
using P = pair<Int, Int>;
vector<vector<P>> G(n);
Dijkstra<Int> D(n+k);
LowestCommonAncestor lca(n);
for(Int i=1;i<n;i++){
Int a,b,c;
cin>>a>>b>>c;
a--;b--;
G[a].emplace_back(b,c);
G[b].emplace_back(a,c);
D.add_edge(a,b,c);
D.add_edge(b,a,c);
lca.add_edge(a,b);
}
lca.build(0);
vector<Int> dep(n);
MFP([&](auto dfs,Int v,Int p,Int d)->void{
dep[v]=d;
for(auto[u,c]:G[v])
if(u!=p) dfs(u,v,d+c);
})(0,-1,0);
vector<vector<Int>> X(k),C(n);
vector<Int> ps(k);
for(Int i=0;i<k;i++){
Int m;
cin>>m>>ps[i];
X[i].resize(m);
for(Int j=0;j<m;j++){
cin>>X[i][j],X[i][j]--;
C[X[i][j]].emplace_back(i);
D.add_edge(X[i][j],n+i,ps[i]);
D.add_edge(n+i,X[i][j],0);
}
}
const Int INF = 1e18;
vector<vector<Int>> E,dist;
for(Int i=0;i<k;i++){
D.build(n+i);
E.emplace_back(k,INF);
dist.emplace_back(n);
for(Int v=0;v<n;v++){
for(Int c:C[v]) chmin(E[i][c],D[v]);
dist[i][v]=D[v];
}
}
Int q;
cin>>q;
for(Int i=0;i<q;i++){
Int u,v;
cin>>u>>v;
u--;v--;
Int ans=dep[u]+dep[v]-2*dep[lca.lca(u,v)];
for(Int x=0;x<k;x++)
for(Int y=0;y<k;y++)
chmin(ans,dist[x][u]+E[x][y]+ps[x]+(x!=y)*ps[y]+dist[y][v]);
cout<<ans<<newl;
}
return 0;
}
beet