通过先到一个点的距离,然后去遍历所有点
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read(){
ll ret=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-f;ch=getchar();}
while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
inline void write(ll zx){
if(zx<0) putchar('-'),zx=-zx;
if(zx<10) putchar(zx+'0');
else{
write(zx/10);
putchar(zx%10+'0');
}
}
int fir[200010],nxt[200010],w[200010],son[200010],tot,n;
ll a[100010],dis[100010],Min,ans;
void add(ll x,ll y,ll z){
++tot;
son[tot]=y;
nxt[tot]=fir[x];
fir[x]=tot;
w[tot]=z;
}
void dfs(ll zx,ll fa){
for(ll i=fir[zx];i;i=nxt[i]){
if(son[i]!=fa){
dfs(son[i],zx);
a[zx]+=a[son[i]];//计算有几个游客
dis[zx]+=dis[son[i]]+a[son[i]]*w[i];//到这个节点的代价
}
}
}
void fs(ll zx,ll fa){
for(ll i=fir[zx];i;i=nxt[i]){
if(son[i]!=fa){
dis[son[i]]=dis[zx]-w[i]*a[son[i]]+w[i]*(a[1]-a[son[i]]);
// 这个点到祖先+这条边要用几次。
//自己的子树不用走这个点(a[son[i]]),所以其他(a[1]-a[son[i]])要走
//在dis[zx]里又多算了(w[i]*a[son[i]])次
//dis[zx]-w[i]*a[son[i]] (先不算这条边)
//dis[zx]-w[i]*a[son[i]]+w[i]*(a[1]-a[son[i]]) {加上其他点走这条边}
fs(son[i],zx);
}
}
}
int main(){
n=read();
for(ll i=1;i<=n;i++) a[i]=1;
for(ll i=1;i<=n-1;i++){
ll x=read(),y=read();
add(x,y,1);
add(y,x,1);
}
dfs(1,0);
fs(1,0);
Min=2e18;
for(ll i=1;i<=n;i++)if(Min>dis[i])Min=dis[i],ans=i;
write(ans);
cout<<' ';
write(Min);putchar('\n');
return 0;
}