結果
| 問題 |
No.1308 ジャンプビーコン
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-12-05 05:09:48 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 6,480 bytes |
| コンパイル時間 | 2,629 ms |
| コンパイル使用メモリ | 211,624 KB |
| 最終ジャッジ日時 | 2025-01-16 17:13:46 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 3 WA * 15 TLE * 19 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i=0; i<n; i++)
#define pb push_back
typedef long long ll;
typedef pair<int, ll> P1;
typedef pair<int, int> P2;
ll N, Q, C;
vector<P1> G[3010];
vector<vector<ll>> dists;
int x[3010];
vector<ll> bfs(int s) {
queue<int> q;
q.push(s);
vector<ll> dist(N);
rep(i, N) dist[i] = -1;
dist[s] = 0;
while (q.size()) {
int v = q.front(); q.pop();
rep(i, G[v].size()) {
P1 p = G[v][i];
int nv = p.first;
ll w = p.second;
if (dist[nv]==-1) {
dist[nv] = dist[v]+w;
q.push(nv);
}
}
}
return dist;
}
int ceil_pow2(int n) {
int x = 0;
while ((1U << x) < (unsigned int)(n)) x++;
return x;
}
template <class S,
S (*op)(S, S),
S (*e)(),
class F,
S (*mapping)(F, S),
F (*composition)(F, F),
F (*id)()>
struct lazy_segtree {
public:
lazy_segtree() : lazy_segtree(0) {}
lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
log = ceil_pow2(_n);
size = 1 << log;
d = std::vector<S>(2 * size, e());
lz = std::vector<F>(size, id());
for (int i = 0; i < _n; i++) d[size + i] = v[i];
for (int i = size - 1; i >= 1; i--) {
update(i);
}
}
void set(int p, S x) {
assert(0 <= p && p < _n);
p += size;
for (int i = log; i >= 1; i--) push(p >> i);
d[p] = x;
for (int i = 1; i <= log; i++) update(p >> i);
}
S get(int p) {
assert(0 <= p && p < _n);
p += size;
for (int i = log; i >= 1; i--) push(p >> i);
return d[p];
}
S prod(int l, int r) {
assert(0 <= l && l <= r && r <= _n);
if (l == r) return e();
l += size;
r += size;
for (int i = log; i >= 1; i--) {
if (((l >> i) << i) != l) push(l >> i);
if (((r >> i) << i) != r) push(r >> i);
}
S sml = e(), smr = e();
while (l < r) {
if (l & 1) sml = op(sml, d[l++]);
if (r & 1) smr = op(d[--r], smr);
l >>= 1;
r >>= 1;
}
return op(sml, smr);
}
S all_prod() { return d[1]; }
void apply(int p, F f) {
assert(0 <= p && p < _n);
p += size;
for (int i = log; i >= 1; i--) push(p >> i);
d[p] = mapping(f, d[p]);
for (int i = 1; i <= log; i++) update(p >> i);
}
void apply(int l, int r, F f) {
assert(0 <= l && l <= r && r <= _n);
if (l == r) return;
l += size;
r += size;
for (int i = log; i >= 1; i--) {
if (((l >> i) << i) != l) push(l >> i);
if (((r >> i) << i) != r) push((r - 1) >> i);
}
{
int l2 = l, r2 = r;
while (l < r) {
if (l & 1) all_apply(l++, f);
if (r & 1) all_apply(--r, f);
l >>= 1;
r >>= 1;
}
l = l2;
r = r2;
}
for (int i = 1; i <= log; i++) {
if (((l >> i) << i) != l) update(l >> i);
if (((r >> i) << i) != r) update((r - 1) >> i);
}
}
private:
int _n, size, log;
std::vector<S> d;
std::vector<F> lz;
void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
void all_apply(int k, F f) {
d[k] = mapping(f, d[k]);
if (k < size) lz[k] = composition(f, lz[k]);
}
void push(int k) {
all_apply(2 * k, lz[k]);
all_apply(2 * k + 1, lz[k]);
lz[k] = id();
}
};
ll op(ll x, ll y) {return min(x, y);}
ll e() {return 1000000000000000000;}
ll mapping(ll f, ll x) {return min(f, x);}
ll composition(ll f, ll g) {return min(f, g);}
ll id() {return 1000000000000000000;}
int par[3010], siz[3010], depth[3010];
int dfs1(int v, int pv, int d) {
par[v] = pv;
siz[v] = 1;
depth[v] = d;
rep(i, G[v].size()) {
int nv = G[v][i].first;
if (nv==pv) continue;
siz[v] += dfs1(nv, v, d+1);
}
return siz[v];
}
int in_order[3010], top[3010];
int in_order_now;
void dfs2(int v, int pv, int top_node) {
in_order[v] = in_order_now;
in_order_now++;
top[v] = top_node;
if (siz[v]==1) return;
int M = 0;
int heavy_node = -1;
rep(i, G[v].size()) {
int nv = G[v][i].first;
if (nv==pv) continue;
if (siz[nv]>M) {
M = siz[nv];
heavy_node = nv;
}
}
dfs2(heavy_node, v, top_node);
rep(i, G[v].size()) {
int nv = G[v][i].first;
if (nv==pv) continue;
if (nv!=heavy_node) dfs2(nv, v, nv);
}
}
vector<P2> query(int u, int v) {
vector<P2> res;
while (top[u]!=top[v]) {
if (depth[top[u]]<=depth[top[v]]) {
res.pb(P2(in_order[top[v]], in_order[v]));
v = par[top[v]];
}
else {
res.pb(P2(in_order[top[u]], in_order[u]));
u = par[top[u]];
}
}
res.pb(P2(min(in_order[u], in_order[v]), max(in_order[u], in_order[v])));
return res;
}
int main() {
//ループ変数が被っていないか?
//制約を確認しているか?
//変数のtypoがないか?
cin.tie(0); ios::sync_with_stdio(false);
cin >> N >> Q >> C;
rep(i, N-1) {
int u, v; cin >> u >> v;
ll l; cin >> l;
G[u-1].pb(P1(v-1, l));
G[v-1].pb(P1(u-1, l));
}
rep(i, N) dists.pb(bfs(i));
rep(i, Q) cin >> x[i];
rep(i, Q) x[i]--;
dfs1(0, -1, 0);
dfs2(0, -1, 0);
lazy_segtree<ll, op, e, ll, mapping, composition, id> lst1(N);
lst1.set(in_order[x[0]], 0);
for (int i=1; i<Q; i++) {
lazy_segtree<ll, op, e, ll, mapping, composition, id> lst2(N);
rep(j, N) {
lst2.apply(in_order[j], in_order[j]+1, lst1.get(j)+dists[x[i-1]][x[i]]);
vector<P2> section = query(j, x[i]);
ll v = lst1.get(in_order[j])+min(C, dists[x[i-1]][j])+dists[j][x[i]];
rep(k, section.size()) {
ll l = section[k].first, r = section[k].second;
lst2.apply(l, r+1, v);
}
}
swap(lst1, lst2);
}
cout << lst1.all_prod() << endl;
}