acwing|【acwing】846. 树的重心**

穿越隧道
DFS

【acwing|【acwing】846. 树的重心**】题意:删掉树中的一个点(及该点的所有边)。
剩下的连通块中,每个联通块中的结点数是多少。
题意要求连不同通块中点的数量的最大值 里面的最小值。
#include using namespace std; const int N = 1e6 + 10; //1e5 + 10,会wa; 可能数据量变大了 int h[N],e[N],ne[N],idx; int n; int ans = N; //要找最小的ans,此时给ans赋予一个本题最大的值。 void add(int a,int b){ e[idx] = b, ne[idx] = h[a],h[a] = idx++; } bool st[N]; int dfs(int u){//算以u为根节点的子树中点的数量 int sum = 1, res = 0; // st[u] = true; //访问过的点就不再访问了 for(int i = h[u]; i != -1; i = ne[i]){ int j = e[i]; if(!st[j]){ int s = dfs(j); //s是以j为根节点中子树结点的数量 res = max(res,s); //找连通块的子树结点最多的值 sum += s; //j同样为是u的子树 } } 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; }

    推荐阅读