結果

問題 No.1308 ジャンプビーコン
ユーザー IKyoproIKyopro
提出日時 2020-12-05 16:07:26
言語 C++17
(gcc 13.2.0 + boost 1.83.0)
結果
AC  
実行時間 2,838 ms / 4,000 ms
コード長 4,949 bytes
コンパイル時間 3,986 ms
コンパイル使用メモリ 248,696 KB
実行使用メモリ 196,196 KB
最終ジャッジ日時 2023-10-13 22:12:34
合計ジャッジ時間 45,465 ms
ジャッジサーバーID
(参考情報)
judge15 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,352 KB
testcase_01 AC 1 ms
4,356 KB
testcase_02 AC 1 ms
4,348 KB
testcase_03 AC 2 ms
4,348 KB
testcase_04 AC 1 ms
4,348 KB
testcase_05 AC 2 ms
4,352 KB
testcase_06 AC 1 ms
4,352 KB
testcase_07 AC 2 ms
4,348 KB
testcase_08 AC 4 ms
4,352 KB
testcase_09 AC 3 ms
4,348 KB
testcase_10 AC 4 ms
4,352 KB
testcase_11 AC 3 ms
4,348 KB
testcase_12 AC 4 ms
4,352 KB
testcase_13 AC 180 ms
15,200 KB
testcase_14 AC 175 ms
15,456 KB
testcase_15 AC 185 ms
15,192 KB
testcase_16 AC 178 ms
15,124 KB
testcase_17 AC 177 ms
15,136 KB
testcase_18 AC 2,709 ms
196,052 KB
testcase_19 AC 2,805 ms
195,960 KB
testcase_20 AC 2,838 ms
196,028 KB
testcase_21 AC 2,758 ms
196,196 KB
testcase_22 AC 2,714 ms
196,048 KB
testcase_23 AC 2 ms
4,352 KB
testcase_24 AC 3 ms
4,352 KB
testcase_25 AC 2 ms
4,348 KB
testcase_26 AC 993 ms
195,988 KB
testcase_27 AC 1,017 ms
195,972 KB
testcase_28 AC 1,003 ms
196,032 KB
testcase_29 AC 2,406 ms
195,968 KB
testcase_30 AC 2,373 ms
195,972 KB
testcase_31 AC 2,792 ms
196,112 KB
testcase_32 AC 1,880 ms
196,032 KB
testcase_33 AC 2,388 ms
196,108 KB
testcase_34 AC 1,004 ms
196,044 KB
testcase_35 AC 1,001 ms
195,968 KB
testcase_36 AC 1,528 ms
196,048 KB
testcase_37 AC 1,538 ms
196,112 KB
testcase_38 AC 2,577 ms
196,048 KB
testcase_39 AC 2,558 ms
196,036 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define rep(i,n) for(int i=0;i<(n);i++)
#define drep(i,n) for(int i=(n)-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

struct edge{
    int to,d;
};

template<typename OperatorMonoid,typename H>
struct DualSegmentTree {
    int sz, height;
    vector<OperatorMonoid> lazy;
    const H h;
    const OperatorMonoid OM0;
    DualSegmentTree(int n, const H h, const OperatorMonoid OM0)
        : h(h), OM0(OM0) {
        sz = 1;
        height = 0;
        while(sz<n) sz <<= 1, height++;
        lazy.assign(2*sz, OM0);
    }

    inline void propagate(int k) {
        if(lazy[k] != OM0) {
            lazy[2*k] = h(lazy[2*k], lazy[k]);
            lazy[2*k+1] = h(lazy[2*k+1], lazy[k]);
            lazy[k] = OM0;
        }
    }

    inline void thrust(int k) {
        for(int i=height;i>0;i--) propagate(k>>i);
    }

    void update(int a, int b, const OperatorMonoid &x) {
        thrust(a += sz);
        thrust(b += sz-1);
        for(int l=a,r=b+1;l<r;l>>=1,r>>=1) {
            if(l&1) lazy[l] = h(lazy[l],x),++l;
            if(r&1) --r,lazy[r] = h(lazy[r],x);
        }
    }

    OperatorMonoid operator[](int k) {
        thrust(k += sz);
        return lazy[k];
    }
};


class HeavLightDecomposition{
public:
    vvec<edge> g;
    vec<int> sz,in,out,head,par;
    int pos;

    void dfs_sz(int cur,int p){
        sz[cur] = 1;
        par[cur] = p;
        for(auto& e:g[cur]) if(e.to!=p){
            dfs_sz(e.to,cur);
            sz[cur] += sz[e.to];
            if(sz[e.to]>sz[g[cur][0].to]) swap(e,g[cur][0]);
        }
    }

    void dfs_hld(int cur,int p){
        in[cur] = pos++;
        for(auto& e:g[cur]) if(e.to!=p){
            head[e.to] = (e.to==g[cur][0].to? head[cur]:e.to);
            dfs_hld(e.to,cur);
        }
        out[cur] = pos;
    }
public:
    HeavLightDecomposition(){}
    HeavLightDecomposition(int N,int root,vvec<edge> tree):
    g(tree),sz(N),in(N),out(N),head(N),par(N){
        pos = 0;
        dfs_sz(root,-1);
        dfs_hld(root,-1);
    }

    int lca(int u,int v){
        while(true){
            if(in[u]>in[v]) swap(u,v);
            if(head[u]==head[v]) return u;
            v = par[head[v]];
        }
    }

    template<class T,class G>
    void update(int u,int v,const T& x,const G& g, bool isedge=false){
        while(true){
            if(in[u]>in[v]) swap(u,v);
            if(head[u]==head[v]) break;
            g(in[head[v]],in[v]+1,x);
            v = par[head[v]];
        }
        g(in[u]+isedge,in[v]+1,x);
    }


    template<class T,class F,class Q>
    T query(int u,int v,const T &e,const F& f,const Q& q,bool isedge=false){
        T l = e,r = e;
        while(true){
            if(in[u]>in[v]){
                swap(u,v); swap(l,r);
            }
            if(head[u]==head[v]) break;
            l = f(q(in[head[v]],in[v]+1),l);
            v = par[head[v]];
        }
        //非可換演算のときは左を反転!
        //f(rev(f(q(a,b),l),r);
        return f(f(q(in[u]+isedge,in[v]+1),l),r);
    }
};

constexpr ll inf = 1e18;

auto op = [](ll a,ll b){return min(a,b);};


int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,Q,C;
    cin >> N >> Q >> C;
    vvec<edge> g(N);
    rep(i,N-1){
        int a,b,c;
        cin >> a >> b >> c;
        a--,b--;
        g[a].push_back({b,c});
        g[b].push_back({a,c});
    }
    vec<int> X(Q);
    rep(i,Q){
        cin >> X[i];
        X[i]--;
    }
    HeavLightDecomposition HLD(N,0,g);
    vec<ll> D(N);
    auto dfs = [&](auto&& self,int cur,int par)->void{
        for(auto& [to,d]:g[cur]) if(to!=par){
            D[to] = D[cur]+d;
            self(self,to,cur);
        }
    };
    dfs(dfs,0,-1);
    auto dist = [&](int a,int b){
        return D[a]+D[b]-2*D[HLD.lca(a,b)];
    };

    DualSegmentTree seg(N,op,inf);
    vec<decltype(seg)> dp;
    rep(i,Q) dp.push_back(seg);
    dp[0].update(HLD.in[X[0]],HLD.in[X[0]]+1,0);
    rep(i,Q-1){
        auto update = [&](int l,int r,ll x){
            dp[i+1].update(l,r,x);
        };
        ll best = inf;
        rep(j,N){
            int n = HLD.in[j];
            if(dp[i][n]==inf) continue;
            ll val = dp[i][n]+dist(X[i],X[i+1]);
            HLD.update(j,j,val,update);
            chmin(best,val);
            ll c = dp[i][n]+dist(j,X[i+1])+C;
            HLD.update(j,X[i+1],c,update);
        }
        HLD.update(X[i],X[i+1],best,update);
    }
    ll ans = inf;
    rep(i,N) chmin(ans,dp[Q-1][i]);
    cout << ans << "\n";
}
0