NC229068. 孤独
描述
对着相遇的幻景挥手作别憧憬着这片天空手心里流逝的岁月像一朵孤独的花瓣一样重复着疼痛,知道了相遇——《茜さす》
输入描述
一行一个整数n,表示节点个数(节点编号从1开始)接下来n−1行,每行两个整数,表示一条边x,y
输出描述
一行表示最小情况下,最大连通块的大小。
示例1
输入:
10 2 1 3 2 4 1 5 2 6 5 7 4 8 6 9 7 10 3
输出:
2
说明:
示例2
输入:
2 1 2
输出:
1
C++(g++ 7.5.0) 解法, 执行用时: 934ms, 内存消耗: 77356K, 提交时间: 2022-12-20 16:04:44
#include <bits/stdc++.h> using namespace std; typedef long long ll; int ans = INT_MAX, n; int sz[1000006]; int dp[1000006]; vector<int>vec[1000006]; void dfs(int i, int fa) { sz[i] = 1; int mx1 = 0; int mx2 = 0; int mx3 = 0; //第三大的子树 for (auto j : vec[i]) { if (j == fa)continue; dfs(j, i); sz[i] += sz[j]; if (sz[j] > sz[mx1]) { mx3 = mx2; mx2 = mx1; mx1 = j; } else if (sz[j] > sz[mx2]) { mx3 = mx2; mx2 = j; } else if (sz[j] > sz[mx3]) { mx3 = j; } dp[i] = max(dp[mx1], sz[mx2]); } ans = min(ans, max(n - sz[i], max(dp[mx1], max(dp[mx2], sz[mx3])))); } int main() { int i, j, x, y; scanf("%d", &n); for (i = 1; i < n; i++) { scanf("%d%d", &x, &y); vec[x].push_back(y); vec[y].push_back(x); } dfs(1, 0); printf("%d\n", ans); return 0; }
C++ 解法, 执行用时: 696ms, 内存消耗: 64180K, 提交时间: 2021-10-24 15:40:13
#include <bits/stdc++.h> using namespace std; const int N=1e6+10; int n,sz[N],sig[N]; vector<int> g[N]; int res=2e9; void dfs(int u,int fa){ int mx=0,se=0,th=0; sz[u]=1; for(auto y:g[u]){ if(y==fa) continue; dfs(y,u); sz[u]+=sz[y]; if(sz[y]>=sz[mx]) { th=se;se=mx;mx=y; }else if(sz[y]>=sz[se]) { th=se;se=y; }else if(sz[y]>=sz[th]) th=y; } sig[u]=max(sig[mx],sz[se]); res=min(res,max({sz[th],sig[mx],sig[se],n-sz[u]})); } int main() { scanf("%d",&n); for(int i=1;i<n;i++){ int x,y;scanf("%d %d",&x,&y); g[x].push_back(y); g[y].push_back(x); } dfs(1,0); res=max(res,1); cout<<res<<'\n'; }