标签:name contest tree art star == i++ efi last
我发现我构造题好弱啊啊啊。
很明显能想到先找到重心, 然后我们的目标就是把所有点接到重心的儿子上,让重心的儿子子树变成菊花图,
这个先把重心到儿子的边连到 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 构造 + 树的重心
标签:name contest tree art star == i++ efi last
原文地址:https://www.cnblogs.com/CJLHY/p/10254485.html