1. 程式人生 > >AIM Tech Round 4 (Div. 1) C - Upgrading Tree 構造 + 樹的重心

AIM Tech Round 4 (Div. 1) C - Upgrading Tree 構造 + 樹的重心

sca def dfs clas 菊花 %d href 發現 enter

C - Upgrading Tree

我發現我構造題好弱啊啊啊。

很明顯能想到先找到重心, 然後我們的目標就是把所有點接到重心的兒子上,讓重心的兒子子樹變成菊花圖,

這個先把重心到兒子的邊連到 i , 然後把 i 到 其 fa 的邊連到重心的兒子上, 一直循環就好啦。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define
PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long using namespace std; const int N = 2e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); int n, last, start, who, sum[N]; vector
<int> G[N]; vector<pair<int,PII>> ans; PII getCenter(int u, int fa) { PII tmp = mk(inf, u); sum[u] = 1; int mx = 0; for(int v : G[u]) { if(v == fa) continue; tmp = min(tmp, getCenter(v, u)); sum[u] += sum[v]; mx = max(mx, sum[v]); } mx
= max(mx, n-sum[u]); return min(tmp, mk(mx, u)); } void work(int u, int fa) { sum[u] = 1; for(int v : G[u]) if(v != fa) work(v, u), sum[u] += sum[v]; } void dfs(int u, int fa) { if(fa != who) { ans.push_back(mk(who, mk(last, u))); ans.push_back(mk(u, mk(fa, start))); last = u; } for(int v : G[u]) if(v != fa) dfs(v, u); } void solve(int u, int fa) { who = u; for(int v : G[u]) { if(v == fa) continue; start = v; last = v; dfs(v, u); ans.push_back(mk(u, mk(last, v))); } } int main() { scanf("%d", &n); for(int i = 1; i < n; i++) { int u, v; scanf("%d%d", &u, &v); G[u].push_back(v); G[v].push_back(u); } int root = getCenter(1, 0).se, root2 = -1; work(root, 0); for(int v : G[root]) if(n % 2 == 0 && sum[v] == n/2) root2 = v; if(~root2) solve(root, root2), solve(root2, root); else solve(root, 0); printf("%d\n", ans.size()); for(auto t : ans) printf("%d %d %d\n", t.fi, t.se.fi, t.se.se); return 0; } /* */

AIM Tech Round 4 (Div. 1) C - Upgrading Tree 構造 + 樹的重心