結果
| 問題 |
No.1769 Don't Stop the Game
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-10-29 19:58:47 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,827 bytes |
| コンパイル時間 | 1,337 ms |
| コンパイル使用メモリ | 82,956 KB |
| 最終ジャッジ日時 | 2025-01-25 08:14:56 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 17 TLE * 11 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:150:21: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
150 | int n; scanf("%d", &n);
| ~~~~~^~~~~~~~~~
main.cpp:154:35: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
154 | int u, v, w; scanf("%d%d%d", &u, &v, &w);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~
ソースコード
// #include <testlib.h>
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#define NDEBUG
using i64 = long long;
struct solve_t {
std::vector<std::vector<int>> g;
std::vector<int> a, b, c;
solve_t(int n): g(n) {}
void add_edge(int u, int v, int w) {
g[u].push_back(a.size());
g[v].push_back(a.size());
a.push_back(u);
b.push_back(v);
c.push_back(w);
}
i64 solve(int start = 0) {
i64 answer = (i64)g.size() * ((i64)g.size() - 1);
std::vector<bool> deleted(g.size());
auto solve = [&](auto&& solve, int root) -> void {
static std::vector<int> size(g.size());
auto calc_size = [&](auto&& dfs, int v, int par) -> int {
size[v] = 1;
for(int id: g[v]) {
int to = v ^ a[id] ^ b[id];
if(to == par or deleted[to]) continue;
size[v] += dfs(dfs, to, v);
}
return size[v];
}; calc_size(calc_size, root, -1);
auto get_centroid = [&](auto&& dfs, int v, int par) -> int {
for(int id: g[v]) {
int to = v ^ a[id] ^ b[id];
if(to == par or deleted[to]) continue;
if(size[to] > size[root] / 2) return dfs(dfs, to, v);
}
return v;
};
int centroid = get_centroid(get_centroid, root, -1);
// 分割統治
deleted[centroid] = true;
for(int id: g[centroid]) {
int to = centroid ^ a[id] ^ b[id];
if(deleted[to]) continue;
solve(solve, to);
}
deleted[centroid] = false;
calc_size(calc_size, centroid, -1);
#ifndef NDEBUG
printf("root: %d\n", root + 1);
printf("centroid: %d\n", centroid + 1);
for(auto e: deleted) printf("%d ", (int)e); puts("");
for(auto e: size) printf("%d ", e); puts("");
for(int id: g[centroid]) if(!deleted[a[id] ^ b[id] ^ centroid])
printf("%d ", (a[id] ^ b[id] ^ centroid) + 1); puts("");
#endif
// [u-centroid-v]
for(int loop = 0; loop < 2; loop++) {
std::map<int, i64> map;
for(int id: g[centroid]) {
int to = centroid ^ a[id] ^ b[id];
if(deleted[to]) continue;
{ // counting 0-xor paths
std::set<int> xor_path; xor_path.insert(0);
auto dfs = [&](auto&& dfs, int v, int par, int xor_val) -> void {
if(loop and xor_path.count(xor_val)) { // [u-centroid]
answer -= size[centroid] - size[to];
}
bool append = false;
if(!xor_path.count(xor_val)) {
answer -= map[xor_val];
xor_path.insert(xor_val);
append = true;
}
for(int id: g[v]) {
int to = v ^ a[id] ^ b[id];
if(to == par or deleted[to]) continue;
dfs(dfs, to, v, xor_val ^ c[id]);
};
if(append) {
xor_path.erase(xor_val);
}
}; dfs(dfs, to, centroid, c[id]);
}
{ // mapping path xors
std::set<int> xor_path;
auto dfs = [&](auto&& dfs, int v, int par, int xor_val) -> void {
bool append = false;
if(!xor_path.count(xor_val)) {
map[xor_val] += size[v];
xor_path.insert(xor_val);
append = true;
}
for(int id: g[v]) {
int to = v ^ a[id] ^ b[id];
if(to == par or deleted[to]) continue;
dfs(dfs, to, v, xor_val ^ c[id]);
};
if(append) {
xor_path.erase(xor_val);
}
}; dfs(dfs, to, centroid, c[id]);
}
}
#ifndef NDEBUG
printf("loop(%d): ", loop);
for(auto [p, q]: map) printf("(%d: %lld), ", p, q); puts("");
printf("%lld\n", answer);
#endif
reverse(begin(g[centroid]), end(g[centroid]));
if(loop) answer -= map[0];
}
#ifndef NDEBUG
puts("");
#endif
}; solve(solve, start);
return answer;
}
};
int main() {
int n; scanf("%d", &n);
solve_t solver(n);
for(int i = 0; i < n - 1; i++) {
int u, v, w; scanf("%d%d%d", &u, &v, &w);
solver.add_edge(u - 1, v - 1, w);
}
printf("%lld\n", solver.solve());
}