From 3c57af7b92f6f02fb4a27c364c3cb96060844868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com> Date: Tue, 9 Jan 2024 13:49:05 +0800 Subject: [PATCH] 'commit' --- TangDou/Topic/HuanGenDp/CF1406.cpp | 52 ------------------- TangDou/Topic/HuanGenDp/CF1406C.cpp | 71 ++++++++++++++++++++++++++ TangDou/Topic/【换根】dfs专题.md | 5 +- 3 files changed, 74 insertions(+), 54 deletions(-) delete mode 100644 TangDou/Topic/HuanGenDp/CF1406.cpp create mode 100644 TangDou/Topic/HuanGenDp/CF1406C.cpp diff --git a/TangDou/Topic/HuanGenDp/CF1406.cpp b/TangDou/Topic/HuanGenDp/CF1406.cpp deleted file mode 100644 index a291eb3..0000000 --- a/TangDou/Topic/HuanGenDp/CF1406.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include -using namespace std; -const int N = 1e5 + 10; -#define int long long -#define endl "\n" - -vector g[N]; -int siz[N], son[N]; -int r1, r2, n; -void dfs(int u, int fa) { - siz[u] = 1; - son[u] = 0; - for (int i = 0; i < g[u].size(); i++) { - int v = g[u][i]; - if (v == fa) continue; - dfs(v, u); - siz[u] += siz[v]; - son[u] = max(son[u], siz[v]); - } - son[u] = max(son[u], n - siz[u]); - if ((son[u] << 1) <= n) r2 = r1, r1 = u; -} -signed main() { - int t; - cin >> t; - while (t--) { - cin >> n; - for (int i = 0; i <= n + 10; i++) g[i].clear(), siz[i] = 0, son[i] = 0; - for (int i = 1; i < n; i++) { - int x, y; - cin >> x >> y; - g[x].push_back(y); - g[y].push_back(x); - } - r1 = r2 = 0; - dfs(1, 0); - if (!r2) { - int r3 = g[r1][0]; - cout << r1 << " " << r3 << endl; - cout << r1 << " " << r3 << endl; - } else { - int r3 = r1; - for (int i = 0; i < g[r2].size(); i++) { - r3 = g[r2][i]; - if (r3 != r1) break; - } - cout << r3 << " " << r2 << endl; - cout << r3 << " " << r1 << endl; - } - } - return 0; -} \ No newline at end of file diff --git a/TangDou/Topic/HuanGenDp/CF1406C.cpp b/TangDou/Topic/HuanGenDp/CF1406C.cpp new file mode 100644 index 0000000..4ef55ac --- /dev/null +++ b/TangDou/Topic/HuanGenDp/CF1406C.cpp @@ -0,0 +1,71 @@ +#include +#define N 100005 +using namespace std; +int n, head[N], ver[2 * N], Next[2 * N], tot = 0; +void add(int x, int y) { + ver[++tot] = y, Next[tot] = head[x], head[x] = tot; +} +vector c; +int mx[N], sz[N]; +int mn = 0x3f3f3f3f; +void dfs(int x, int pre) { + for (int i = head[x]; i; i = Next[i]) { + int y = ver[i]; + if (y == pre) continue; + dfs(y, x); + sz[x] += (sz[y] + 1); + mx[x] = max(mx[x], sz[y] + 1); + } + mx[x] = max(mx[x], n - 1 - sz[x]); + mn = min(mn, mx[x]); +} +void solve() { + cin >> n; + tot = 0; + mn = 0x3f3f3f3f; + c.clear(); + for (int i = 0; i <= n; i++) { + head[i] = 0; + mx[i] = 0; + sz[i] = 0; + } + for (int i = 1; i < n; i++) { + int x, y; + cin >> x >> y; + add(x, y); + add(y, x); + } + dfs(1, 0); + for (int i = 1; i <= n; i++) { + if (mx[i] == mn) { + c.push_back(i); + } + } + if (c.size() == 1) { + for (int i = head[c[0]]; i; i = Next[i]) { + int y = ver[i]; + cout << c[0] << " " << y << endl; + cout << c[0] << " " << y << endl; + return; + } + } else { + int tmp; + for (int i = head[c[0]]; i; i = Next[i]) { + int y = ver[i]; + if (y == c[1]) continue; + cout << c[0] << " " << y << endl; + tmp = y; + break; + } + cout << c[1] << " " << tmp << endl; + return; + } +} +int main() { + int T; + cin >> T; + while (T--) { + solve(); + } + return 0; +} diff --git a/TangDou/Topic/【换根】dfs专题.md b/TangDou/Topic/【换根】dfs专题.md index 43a5928..ede4e2c 100644 --- a/TangDou/Topic/【换根】dfs专题.md +++ b/TangDou/Topic/【换根】dfs专题.md @@ -141,9 +141,10 @@ signed main() { 1、先任选一个结点作为根节点(比如$1$号节点),把无根树变成有根树。然后设$sz[i]$表示以$i$为根节点的子树节点个数。转移方程为$\displaystyle sz[u]=\sum_{fa[v]=u} (sz[v])$ -2、设$son[i]$表示删去节点$x$后剩下的连通分量中最大子树节点个数。其中一部分在原来$i$其为根的子树。$son[i]=max(son[i],siz[i的儿子节点])$; +2、设$son[i]$表示删去节点$i$后剩下的连通分量中最大子树节点个数。其中一部分在原来$i$其为根的子树。$\displaystyle son[i]=max(son[i],sz[j])$ +> **解释**:$j$的含义是$i$的所有儿子节点 -另外一部分在$i$的“上方”子树有$n-sz[i]$个。 +另外一部分在$i$的 **上方** 子树有$n-sz[i]$个。 $$son[i]=max(son[i],n-sz[i])$$ ![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202401091310362.png)