[AcWing 846] 樹的重心
阿新 • • 發佈:2022-05-05
點選檢視程式碼
#include<iostream> #include<cstring> using namespace std; const int N = 1e5 + 10, M = 2 * N; int n, ans = N; int h[N], e[M], ne[M], idx; bool st[M]; void add(int a, int b) { e[idx] = b; ne[idx] = h[a]; h[a] = idx ++; } int dfs(int u) { st[u] = true; int sum = 1, res = 0; for (int i = h[u]; i != -1; i = ne[i]) { int j = e[i]; if (!st[j]) { int s = dfs(j); res = max(res, s); sum += s; } } res = max(res, n - sum); ans = min(ans, res); return sum; } int main() { cin >> n; memset(h, -1, sizeof(h)); for (int i = 0; i < n - 1; i ++) { int a, b; cin >> a >> b; add(a, b); add(b, a); } dfs(1); cout << ans << endl; return 0; }
- 使用鄰接表儲存樹的結構,a 和 b 存在一條邊這個操作的實現方式:使用頭插法在 a 的位置插入 b,在 b 的位置插入 a;
- 使用 dfs 進行搜尋,dfs 首先會執行 st[u] = true,再往下執行 dfs 只會往 u 的下面分支進行搜尋,不會回到 u 這個分支,故對任意一個節點 u,都可以分為兩部分,一部分是 u 下面的分支(可能不止一個分支),這部分可以通過 dfs 獲得節點個數,另一部分是 u 的上面分支,可以用 n - sum 計算得到上面分支的節點個數,其中 sum = 1(節點 u) + s(下面所有分支的節點個數,是一個累加值);
- res 是對於一個節點,所有分支的節點個數中的最大值,ans 是所有的 res 中的最小值;