結果

問題 No.1308 ジャンプビーコン
ユーザー IKyoproIKyopro
提出日時 2020-12-05 16:04:40
言語 C++17
(gcc 13.2.0 + boost 1.83.0)
結果
TLE  
実行時間 -
コード長 4,809 bytes
コンパイル時間 2,607 ms
コンパイル使用メモリ 219,736 KB
実行使用メモリ 196,296 KB
最終ジャッジ日時 2023-10-13 22:10:49
合計ジャッジ時間 44,802 ms
ジャッジサーバーID
(参考情報)
judge11 / judge12
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
8,700 KB
testcase_01 AC 1 ms
4,352 KB
testcase_02 AC 2 ms
4,352 KB
testcase_03 AC 2 ms
4,356 KB
testcase_04 AC 2 ms
4,348 KB
testcase_05 AC 2 ms
4,348 KB
testcase_06 AC 2 ms
4,348 KB
testcase_07 AC 2 ms
4,348 KB
testcase_08 AC 5 ms
4,352 KB
testcase_09 AC 4 ms
4,352 KB
testcase_10 AC 4 ms
4,348 KB
testcase_11 AC 4 ms
4,348 KB
testcase_12 AC 4 ms
4,348 KB
testcase_13 AC 269 ms
15,628 KB
testcase_14 AC 259 ms
15,220 KB
testcase_15 AC 276 ms
15,156 KB
testcase_16 AC 257 ms
15,172 KB
testcase_17 AC 259 ms
15,532 KB
testcase_18 TLE -
testcase_19 TLE -
testcase_20 TLE -
testcase_21 TLE -
testcase_22 TLE -
testcase_23 AC 2 ms
4,348 KB
testcase_24 AC 2 ms
4,348 KB
testcase_25 AC 3 ms
4,352 KB
testcase_26 AC 1,352 ms
196,120 KB
testcase_27 AC 1,397 ms
195,964 KB
testcase_28 AC 1,369 ms
196,104 KB
testcase_29 AC 3,429 ms
196,108 KB
testcase_30 AC 3,417 ms
196,000 KB
testcase_31 TLE -
testcase_32 -- -
testcase_33 -- -
testcase_34 -- -
testcase_35 -- -
testcase_36 -- -
testcase_37 -- -
testcase_38 -- -
testcase_39 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

#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);
        };
        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);
            HLD.update(X[i],X[i+1],val,update);
            ll c = dp[i][n]+dist(j,X[i+1])+C;
            HLD.update(j,X[i+1],c,update);
        }
    }
    ll ans = inf;
    rep(i,N) chmin(ans,dp[Q-1][i]);
    cout << ans << "\n";
}
0