给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大
给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大
给出一个数字N,代表有N个点.N<=1000000 下面N-1条边.
输出你所找到的点,如果具有多个解,请输出编号最小的那个.
题解: 先把1当作根求出总和,然后转移即可。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define N 2000003 using namespace std; int n,m; int point[N],next[N],v[N],deep[N],tot,size[N]; long long f[N],ans; int ansx; void add(int x,int y) { tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y; tot++; next[tot]=point[y]; point[y]=tot; v[tot]=x; } void dfs(int x,int fa) { size[x]=1; for (int i=point[x];i;i=next[i]) if (v[i]!=fa) { dfs(v[i],x); deep[v[i]]=deep[x]+1; size[x]+=size[v[i]]; } } void dp(int x,int fa) { for (int i=point[x];i;i=next[i]) if (v[i]!=fa) { f[v[i]]=(long long)f[x]-(long long)size[v[i]]+(long long)n-size[v[i]]; if (ans<f[v[i]]) ans=f[v[i]],ansx=v[i]; if (ans==f[v[i]]&&ansx>v[i]) ansx=v[i]; dp(v[i],x); } } int main() { scanf("%d",&n); for (int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); add(x,y); } deep[1]=1; dfs(1,0); for (int i=1;i<=n;i++) f[1]+=(long long)deep[i]; ans=f[1],ansx=1; dp(1,0); printf("%d\n",ansx); }