提出 #52108472
ソースコード 拡げる
Copy
#include <stdio.h>#include <stdlib.h>#include <inttypes.h>struct edge_s {int to, id, rev_id;};int ec[114514];struct edge_s *es[114514];void ae(int f, int t, int id, int rev_id) {es[f] = realloc(es[f], sizeof(*es[f]) * (ec[f] + 1));if (es[f] == NULL) exit(2);es[f][ec[f]].to = t;es[f][ec[f]].id = id;es[f][ec[f]].rev_id = rev_id;ec[f]++;}int N;
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
struct edge_s {
int to, id, rev_id;
};
int ec[114514];
struct edge_s *es[114514];
void ae(int f, int t, int id, int rev_id) {
es[f] = realloc(es[f], sizeof(*es[f]) * (ec[f] + 1));
if (es[f] == NULL) exit(2);
es[f][ec[f]].to = t;
es[f][ec[f]].id = id;
es[f][ec[f]].rev_id = rev_id;
ec[f]++;
}
int N;
int A[114514], B[114514];
int C[114514];
struct meow_s {
uint64_t f_value;
uint64_t sum_of_C;
};
struct meow_s memo[114514];
char memo_status[114514];
struct meow_s delta_cache[114514 * 2];
struct edge_s memo_tarinai[114514];
struct meow_s calc(int node, int from_edge_id) {
struct meow_s ret = {0, 0};
int i;
if (memo_status[node] == 0) {
/* メモが全く無い */
for (i = 0; i < ec[node]; i++) {
if (es[node][i].rev_id == from_edge_id) {
memo_tarinai[node] = es[node][i];
} else {
struct meow_s delta = calc(es[node][i].to, es[node][i].id);
/* 下層の分を足し、さらに上がったので C_i の合計を足す */
ret.f_value += delta.f_value + delta.sum_of_C;
/* 新しい C_i の合計を求める */
ret.sum_of_C += delta.sum_of_C;
/* キャッシュする */
delta_cache[es[node][i].rev_id] = delta;
}
}
ret.sum_of_C += C[node];
memo[node] = ret;
memo_status[node] = from_edge_id < 0 ? 2 : 1;
return ret; /* 分岐で抜いているので、来た辺の分のロールバックは不要 */
}
if (memo_status[node] == 1) {
/* 欠けている場所がある */
if (memo_tarinai[node].rev_id == from_edge_id) {
/* 同じ場所が欠けている */
return memo[node];
} else {
/* 違う場所が欠ける → 埋めることができる */
struct meow_s delta = calc(memo_tarinai[node].to, memo_tarinai[node].id);
/* 下層の分を足し、さらに上がったので C_i の合計を足す */
memo[node].f_value += delta.f_value + delta.sum_of_C;
/* 新しい C_i の合計を求める */
memo[node].sum_of_C += delta.sum_of_C;
/* キャッシュする */
delta_cache[memo_tarinai[node].rev_id] = delta;
/* 欠けが解消したことを記録する */
memo_status[node] = 2;
/* 下のロールバックの処理に行く */
}
}
ret = memo[node];
if (from_edge_id >= 0) {
/* 来た辺の分をロールバック */
ret.f_value -= delta_cache[from_edge_id].f_value + delta_cache[from_edge_id].sum_of_C;
ret.sum_of_C -= delta_cache[from_edge_id].sum_of_C;
}
return ret;
}
int main(void) {
int i;
uint64_t ans;
if (scanf("%d", &N) != 1) return 1;
for (i = 1; i < N; i++) {
if (scanf("%d%d", &A[i], &B[i]) != 2) return 1;
ae(A[i], B[i], 2 * (i - 1), 2 * (i - 1) + 1);
ae(B[i], A[i], 2 * (i - 1) + 1, 2 * (i - 1));
}
for (i = 1; i <= N; i++) {
if (scanf("%d", &C[i]) != 1) return 1;
}
ans = calc(1, -1).f_value;
for (i = 2; i <= N; i++) {
uint64_t candidate = calc(i, -1).f_value;
if (candidate < ans) ans = candidate;
}
printf("%" PRIu64 "\n", ans);
return 0;
}
/*
f(x) = (C_i × そこに行くまでのステップ数) の合計
これをサブツリーについて計算する
単純に C_i の和 → これを1段深くなるごとに加える
*/
提出情報
| 提出日時 | |
|---|---|
| 問題 | E - Minimize Sum of Distances |
| ユーザ | mikecat |
| 言語 | C (gcc 12.2.0) |
| 得点 | 475 |
| コード長 | 3298 Byte |
| 結果 | AC |
| 実行時間 | 54 ms |
| メモリ | 20676 KB |
ジャッジ結果
| セット名 | Sample | All | ||||
|---|---|---|---|---|---|---|
| 得点 / 配点 | 0 / 0 | 475 / 475 | ||||
| 結果 |
|
|
| セット名 | テストケース |
|---|---|
| Sample | example0.txt, example1.txt, example2.txt |
| All | example0.txt, example1.txt, example2.txt, test_00.txt, test_01.txt, test_02.txt, test_03.txt, test_04.txt, test_05.txt, test_06.txt, test_07.txt, test_08.txt, test_09.txt, test_10.txt, test_11.txt, test_12.txt, test_13.txt, test_14.txt, test_15.txt, test_16.txt, test_17.txt, test_18.txt, test_19.txt, test_20.txt, test_21.txt, test_22.txt, test_23.txt, test_24.txt, test_25.txt, test_26.txt, test_27.txt |
| ケース名 | 結果 | 実行時間 | メモリ |
|---|---|---|---|
| example0.txt | AC | 1 ms | 1620 KB |
| example1.txt | AC | 1 ms | 1660 KB |
| example2.txt | AC | 0 ms | 1664 KB |
| test_00.txt | AC | 28 ms | 9352 KB |
| test_01.txt | AC | 18 ms | 6728 KB |
| test_02.txt | AC | 33 ms | 10680 KB |
| test_03.txt | AC | 7 ms | 4184 KB |
| test_04.txt | AC | 27 ms | 11008 KB |
| test_05.txt | AC | 15 ms | 7232 KB |
| test_06.txt | AC | 20 ms | 9264 KB |
| test_07.txt | AC | 19 ms | 9696 KB |
| test_08.txt | AC | 15 ms | 7284 KB |
| test_09.txt | AC | 47 ms | 13820 KB |
| test_10.txt | AC | 40 ms | 13820 KB |
| test_11.txt | AC | 47 ms | 13812 KB |
| test_12.txt | AC | 40 ms | 13680 KB |
| test_13.txt | AC | 48 ms | 13808 KB |
| test_14.txt | AC | 41 ms | 13804 KB |
| test_15.txt | AC | 36 ms | 14384 KB |
| test_16.txt | AC | 30 ms | 14272 KB |
| test_17.txt | AC | 35 ms | 14384 KB |
| test_18.txt | AC | 30 ms | 14260 KB |
| test_19.txt | AC | 37 ms | 14380 KB |
| test_20.txt | AC | 30 ms | 14372 KB |
| test_21.txt | AC | 54 ms | 20564 KB |
| test_22.txt | AC | 44 ms | 20676 KB |
| test_23.txt | AC | 52 ms | 18748 KB |
| test_24.txt | AC | 44 ms | 18004 KB |
| test_25.txt | AC | 50 ms | 19152 KB |
| test_26.txt | AC | 44 ms | 19628 KB |
| test_27.txt | AC | 0 ms | 1672 KB |