Problem:
Problem I: Traffic Tree
Problem
それぞれ1から
N
までの番号が付いた
N
個の頂点が、
N
-1本の無向辺によって繋がれたグラフが与えられる。各頂点について、その頂点からスタートしてすべての頂点を訪れるための最短のステップ数を出力せよ。
ただし、ある頂点から1本の辺をたどって別の頂点に移動することを1ステップとする。
Input
入力は以下の形式で与えられる。
N
u
1
v
1
.
.
.
u
N−1
v
N−1
1行目に、1つの整数
N
が与えられる。
続く
N
-1行のうち
i
行目には
i
番目の辺の両端の頂点番号を表す整数
u
i
,
v
i
が空白区切りで与えられる。
Constraints
2 ≤
N
≤ 10
5
1 ≤
u
i
,
v
i
≤
N
(1 ≤
i
≤
N
-1)
u
i
≠
v
i
与えられるグラフは連結である
Output
頂点1から頂点
N
について
i
行目に頂点
i
からスタートしてすべての頂点を訪れるための最短のステップ数を出力せよ。
Sample Input 1
2
1 2
Sample Output 1
1
1
Sample Input 2
6
1 2
1 3
3 4
3 5
5 6
Sample Output 2
7
6
8
7
7
6
Sample Input2の図

Submitted solutions:

code_snippet: #include <algorithm>
#include <iostream>
#include <iomanip>
#include <limits.h>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include <stack>
#include <complex>
#include <array>
#include <cassert>
#include <random>

using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define all(A) A.begin(), A.end()
#define debug(var) cout << #var << " = " << var << endl;
typedef long long ll;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p)
{
    os << "(" << p.first << "," << p.second << ")";
    return os;
}

template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p)
{
    is >> p.first >> p.second;
    return is;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v)
{
    for (int i = 0; i < (int)v.size(); i++)
    {
        os << v[i] << (i + 1 != (int)v.size() ? " " : "");
    }
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &v)
{
    for (int i = 0; i < (int)v.size(); i++)
    {
        os << v[i] << endl;
    }
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<vector<vector<T>>> &v)
{
    int n = v.size();
    int m = v[0].size();
    int p = v[0][0].size();
    rep(k, p)
    {
        os << "k = " << k << endl;
        rep(i, n)
        {
            rep(j, m)
            {
                os << v[i][j][k];
                if (j < m - 1)
                {
                    os << " ";
                }
                else
                {
                    os << endl;
                }
            }
        }
    }
    return os;
}

template <typename T>
istream &operator>>(istream &is, vector<T> &v)
{
    for (T &in : v)
        is >> in;
    return is;
}

template <typename T, typename S>
ostream &operator<<(ostream &os, map<T, S> &mp)
{
    for (auto &[key, val] : mp)
    {
        os << key << ":" << val << " ";
    }
    cout << endl;
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, set<T> st)
{
    auto itr = st.begin();
    for (int i = 0; i < (int)st.size(); i++)
    {
        os << *itr << (i + 1 != (int)st.size() ? " " : "");
        itr++;
    }
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, multiset<T> st)
{
    auto itr = st.begin();
    for (int i = 0; i < (int)st.size(); i++)
    {
        os << *itr << (i + 1 != (int)st.size() ? " " : "");
        itr++;
    }
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, queue<T> q)
{
    while (q.size())
    {
        os << q.front() << " ";
        q.pop();
    }
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, deque<T> q)
{
    while (q.size())
    {
        os << q.front() << " ";
        q.pop_front();
    }
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, stack<T> st)
{
    while (st.size())
    {
        os << st.top() << " ";
        st.pop();
    }
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, priority_queue<T> pq)
{
    while (pq.size())
    {
        os << pq.top() << " ";
        pq.pop();
    }
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, priority_queue<T, vector<T>, greater<T>> mpq)
{
    while (mpq.size())
    {
        os << mpq.top() << " ";
        mpq.pop();
    }
    return os;
}
template <class E, class V, E (*merge)(E, E), E (*e)(), E (*put_edge)(V, int), V (*put_vertex)(E, int)>
struct RerootingDP {
    struct edge {
        int to, idx, xdi;
    };
    RerootingDP(int n_ = 0) : n(n_), inner_edge_id(0) {
        es.resize(2*n-2);
        start.resize(2*n-2);
        if (n == 1) es_build();
    }
    void add_edge(int u, int v, int idx, int xdi){
        start[inner_edge_id] = u;
        es[inner_edge_id] = {v,idx,xdi};
        inner_edge_id++;
        start[inner_edge_id] = v;
        es[inner_edge_id] = {u,xdi,idx};
        inner_edge_id++;
        if (inner_edge_id == 2*n-2){
            es_build();
        }
    }
    vector<V> build(int root_ = 0){
        root = root_;
        vector<V> subdp(n); subdp[0] = put_vertex(e(),0);
        outs.resize(n);
        vector<int> geta(n+1,0);
        for (int i = 0; i < n; i++) geta[i+1] = start[i+1] - start[i] - 1;
        geta[root+1]++;
        for (int i = 0; i < n; i++) geta[i+1] += geta[i];
        auto dfs = [&](auto sfs, int v, int f) -> void {
            E val = e();
            for (int i = start[v]; i < start[v+1]; i++){
                if (es[i].to == f){
                    swap(es[start[v+1]-1],es[i]);
                }
                if (es[i].to == f) continue;
                sfs(sfs,es[i].to,v);
                E nval = put_edge(subdp[es[i].to],es[i].idx);
                outs[geta[v]++] = nval;
                val = merge(val,nval);
            }
            subdp[v] = put_vertex(val, v);
        };
        dfs(dfs,root,-1);
        return subdp;
    }
    vector<V> reroot(){
        vector<E> reverse_edge(n);
        reverse_edge[root] = e();
        vector<V> answers(n);
        auto dfs = [&](auto sfs, int v) -> void {
            int le = outs_start(v);
            int ri = outs_start(v+1);
            int siz = ri - le;
            vector<E> rui(siz+1);
            rui[siz] = e();
            for (int i = siz-1; i >= 0; i--){
                rui[i] = merge(outs[le+i],rui[i+1]);
            }
            answers[v] = put_vertex(merge(rui[0],reverse_edge[v]),v);
            E lui = e();
            for (int i = 0; i < siz; i++){
                V rdp = put_vertex(merge(merge(lui,rui[i+1]),reverse_edge[v]),v);
                reverse_edge[es[start[v]+i].to] = put_edge(rdp,es[start[v]+i].xdi);
                lui = merge(lui,outs[le+i]);
                sfs(sfs,es[start[v]+i].to);
            }
        };
        dfs(dfs,root);
        return answers;
    }
    private:
    int n, root, inner_edge_id;
    vector<E> outs;
    vector<edge> es;
    vector<int> start;
    int outs_start(int v){
        int res = start[v] - v;
        if (root < v) res++;
        return res;
    }
    void es_build(){
        vector<edge> nes(2*n-2);
        vector<int> nstart(n+2,0);
        for (int i = 0; i < 2*n-2; i++) nstart[start[i]+2]++;
        for (int i = 0; i < n; i++) nstart[i+1] += nstart[i];
        for (int i = 0; i < 2*n-2; i++) nes[nstart[start[i]+1]++] = es[i];
        swap(es,nes);
        swap(start,nstart);
    }
};
using S = long long;
S merge(S a,S b){
    return max(a,b);
}
S e(){
    return 0;
}
S put_edge(S x,int weight){
    return x+weight;
}
S put_vertex(S x,int i){
    return x;
}

int main(){
    int n;
    cin >> n;
    RerootingDP<S,S,merge,e,put_edge,put_vertex> dp(n);
    rep(i,n-1){
        int u,v;
        cin >> u >> v;
        u--;
        v--;
        dp.add_edge(u,v,1,1);
    }
    vector<S> ans = dp.build();
    // debug(ans);
    ans = dp.reroot();
    // debug(ans);
    rep(i,n){
        cout << 2*n-2-ans[i] << endl;
    }
}
accuracy: 1
time_ms: 110
memory_kb: 24628
final_rank: 10

code_snippet: #define _GLGBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;

struct DP
{
    int max_dist;
    int max_dist_vertex;

    bool operator<(const DP &other) const
    {
        if (max_dist != other.max_dist)
            return max_dist < other.max_dist;

        return max_dist_vertex < other.max_dist_vertex;
    }
};

int N, ID = -1, invalid_vertex = -1;
vector<vector<int>> G;
vector<vector<DP>> dp;
vector<DP> ans;

DP dfs(int root, int parent)
{
    int out_degree_of_root = static_cast<int>(G.at(root).size());
    DP max_dp_of_subtree{ID, root};

    dp.at(root) = vector<DP>(out_degree_of_root, DP{ID, invalid_vertex});

    for (int i = 0; i < out_degree_of_root; i++)
    {
        int adjacent = G.at(root).at(i);

        if (adjacent == parent)
            continue;

        dp.at(root).at(i) = dfs(adjacent, root);

        if (max_dp_of_subtree < dp.at(root).at(i))
            max_dp_of_subtree = dp.at(root).at(i);
    }

    return DP{
        max_dp_of_subtree.max_dist + 1,
        max_dp_of_subtree.max_dist_vertex};
}

void dfs_reroot(int root, DP parent_subtree_dp_info, int parent)
{
    int out_degree_of_root = static_cast<int>(G.at(root).size());

    for (int i = 0; i < out_degree_of_root; i++)
        if (G.at(root).at(i) == parent)
            dp.at(root).at(i) = parent_subtree_dp_info;

    vector<DP> dp_prefix(out_degree_of_root + 1, DP{ID, invalid_vertex}), dp_suffix(out_degree_of_root + 1, DP{ID, invalid_vertex});

    for (int i = 0; i < out_degree_of_root; i++)
    {
        if (dp_prefix.at(i) < dp.at(root).at(i))
            dp_prefix.at(i + 1) = dp.at(root).at(i);
        else
            dp_prefix.at(i + 1) = dp_prefix.at(i);
    }

    for (int i = out_degree_of_root - 1; i >= 0; i--)
    {
        if (dp_suffix.at(i + 1) < dp.at(root).at(i))
            dp_suffix.at(i) = dp.at(root).at(i);
        else
            dp_suffix.at(i) = dp_suffix.at(i + 1);
    }

    ans.at(root) = DP{
        dp_prefix.at(out_degree_of_root).max_dist + 1,
        dp_prefix.at(out_degree_of_root).max_dist_vertex};

    for (int i = 0; i < out_degree_of_root; i++)
    {
        int adjacent = G.at(root).at(i);

        if (adjacent == parent)
            continue;

        DP max_dp_info;

        if (dp_prefix.at(i) < dp_suffix.at(i + 1))
            max_dp_info = dp_suffix.at(i + 1);
        else
            max_dp_info = dp_prefix.at(i);

        max_dp_info.max_dist++;

        if (out_degree_of_root == 1)
            max_dp_info.max_dist_vertex = root;

        dfs_reroot(adjacent, max_dp_info, root);
    }
}

int main()
{
    cin >> N;

    G.resize(N);
    dp.resize(N);
    ans.resize(N, DP{ID, invalid_vertex});

    for (int i = 1; i <= N - 1; i++)
    {
        int A, B;
        cin >> A >> B;

        A--, B--;

        G.at(A).push_back(B);
        G.at(B).push_back(A);
    }

    dfs(0, -1);
    dfs_reroot(0, DP{ID, -1}, -1);

    for (int i = 0; i < N; i++)
        cout << 2 * (N - 1) - ans.at(i).max_dist << '\n';

    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 31944
final_rank: 5

code_snippet: // # pragma GCC target("avx2")
// # pragma GCC optimize("O3")
// # pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
// using namespace atcoder;

// #include <boost/multiprecision/cpp_int.hpp>
// using namespace boost::multiprecision;

#define ll long long
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define vi vector<int>
#define vl vector<ll>
#define vd vector<double>
#define vb vector<bool>
#define vs vector<string>
#define vc vector<char>
#define ull unsigned long long
#define chmax(a, b) a = max(a, b)
#define chmin(a, b) a = min(a, b)

// ll inf = (1ll << 61);
// const double PI=3.1415926535897932384626433832795028841971;

// ll rui(ll a,ll b){
//     if(b==0)return 1;
//     if(b%2==1) return a*rui(a*a,b/2);
//     return rui(a*a,b/2);
// }

// ll kai(ll n){
//     if(n==0)return 1;
//     return n*kai(n-1);
// }

// using mint = modint998244353;//static_modint<998244353>
// using mint = modint1000000007;//static_modint<1000000007>
// using mint = static_modint<1923865917>;
// using mint = modint;//mint::set_mod(mod);

// ll const mod=1000000007ll;
// ll const mod=998244353ll;
// ll modrui(ll a,ll b,ll mod){
//     a%=mod;
//     if(b==0)return 1;
//     if(b%2==1) return a*modrui(a*a%mod,b/2,mod)%mod;
//     return modrui(a*a%mod,b/2,mod)%mod;
// }

// ll inv(ll x){
//     x%=mod;
//     return modrui(x,mod-2);
// }

// ll modkai(ll n){
//     ll ret=1;
//     rep(i,n){
//         ret*=(i+1)%mod;
//         ret%=mod;
//     }
//     return ret;
// }

// void incr(vl &v,ll n){//　n進法
//     ll k=v.size();
//     v[k-1]++;
//     ll now=k-1;
//     while (v[now]>=n)
//     {
//         v[now]=0;
//         if(now==0)break;
//         v[now-1]++;
//         now--;
//     }
//     return;
// }







//https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1595
vl memo1(1<<17),memo2(1<<17),ans(1<<17,0);

void dfs(vector<vl> const&g,vl const&par,ll now=0,ll d=0){
    vl v={d,memo1[now],memo2[now]};
    sort(v.begin(),v.end());
    chmax(ans[now],v[2]);
    for(auto &s:g[now]){
        if(memo1[s]+1==v[2]) dfs(g,par,s,v[1]+1);
        else dfs(g,par,s,v[2]+1);
    }
}

void solve(){
    ll n;
    cin >> n;
    vector<vl> g(n);
    vl par(n,-1);
    rep(i,n-1){
        ll u,v;
        cin >> u >> v;
        u--;
        v--;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    deque<ll> dq={0,-1};
    while(!dq.empty()){
        ll x=dq[0],p=dq[1];
        par[x]=p;
        dq.pop_front();dq.pop_front();
        if(p!=-1){
            g[x].erase(find(g[x].begin(),g[x].end(),p));
        }
        for(auto &s:g[x]){
            dq.push_back(s);
            dq.push_back(x);
        }
    }
    vl deg(n);
    rep(i,n){
        deg[i]=g[i].size();
        if(deg[i]==0)dq.push_back(i);
    }
    while(!dq.empty()){
        ll x=dq[0];
        dq.pop_front();
        if(par[x]==-1)continue;
        ll p=par[x];
        if(memo1[p]<=memo1[x]+1){
            memo2[p]=memo1[p];
            memo1[p]=memo1[x]+1;
        }
        else if(memo2[p]<=memo1[x]+1){
            memo2[p]=memo1[x]+1;
        }
        deg[p]--;
        if(deg[p]==0)dq.push_back(p);
    }

    dfs(g,par);

    rep(i,n)cout << (n-1)*2-ans[i] << endl;
}

int main(){
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    ll t = 1;
    // cin >> t;
    while (t--) solve();
}
accuracy: 1
time_ms: 90
memory_kb: 25532
final_rank: 7

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cmath>
#include <cstdint>
#include <iomanip>
#include <bit>
#include <queue>
#include <stack>
//#include <atcoder/all>

using namespace std;

//using mint = atcoder::modint998244353 ;

void ansYesNo(bool ans, string yes = "Yes", string no = "No")
{
    if (ans)
    {
        cout << yes << endl;
    }
    else
    {
        cout << no << endl;
    }
}

struct Costs{
    int64_t child ;
    int64_t cost ;
};

vector<vector<pair<int64_t,int64_t>>> WeightedGraphInput(int Nodes, int Edges, bool Undirected, bool OneIndexed){
    vector<vector<pair<int64_t,int64_t>>> list(Nodes, vector<pair<int64_t,int64_t>>(0)) ;
    int StartIndex = 0 ;
    if (OneIndexed)
    {
        StartIndex = 1 ;
    }
    for (int i = 0; i < Edges; i++)
    {
        int64_t a,b,c ;
        cin >> a >> b ;
        c = 1 ;
        list.at(a-StartIndex).push_back(make_pair(b-StartIndex,c)) ;
        if (Undirected)
        {
            list.at(b-StartIndex).push_back(make_pair(a-StartIndex,c)) ;
        }
    }
    return list ;
}

int64_t calcSubScore(vector<vector<pair<int64_t,int64_t>>> &list, vector<int64_t> &d, vector<int64_t> &SubScore, int node, int p){
    int64_t SS = d.at(node) ;
    for (int i = 0; i < list.at(node).size(); i++)
    {
        int64_t next = list.at(node).at(i).first ;
        int64_t edgec = list.at(node).at(i).second ;
        if (next == p)
        {
            continue;
        }
        SS = max(SS,calcSubScore(list,d,SubScore,next,node) + edgec) ;
    }
    SubScore.at(node) = SS ;
    return SS ;
}

void updateCosts(pair<Costs,Costs> &C, Costs newc){
    if (C.first.cost < newc.cost)
    {
        C.second = C.first ;
        C.first = newc ;
    }else if (C.second.cost < newc.cost)
    {
        C.second = newc ;
    }
    
    return ;
}

int64_t solve(vector<vector<pair<int64_t,int64_t>>> &list, vector<int64_t> &d, vector<int64_t> &SubScore, vector<pair<Costs,Costs>> &dp, int node, int p){
    
    for (int i = 0; i < list.at(node).size(); i++)
    {
        int next = list.at(node).at(i).first ;
        int64_t edgec = list.at(node).at(i).second ;
        if (next == p)
        {
            updateCosts(dp.at(node),Costs(next,d.at(next)+edgec)) ;
            if (dp.at(next).first.child != node)
            {
                updateCosts(dp.at(node),Costs(next,dp.at(next).first.cost+edgec)) ;
            }else if (dp.at(next).second.child != node)
            {
                updateCosts(dp.at(node),Costs(next,dp.at(next).second.cost+edgec)) ;
            }
            
        }else
        {
            updateCosts(dp.at(node),Costs(next,SubScore.at(next)+edgec)) ;
        }
    }

    for (int i = 0; i < list.at(node).size(); i++)
    {
        int next = list.at(node).at(i).first ;
        if(next != p)solve(list,d,SubScore,dp,next,node) ;
    }
    return 0 ;
}

int main(){
    int n ;
    cin >> n ;
    vector<vector<pair<int64_t,int64_t>>> list = WeightedGraphInput(n,n-1,true,true) ;
    vector<int64_t> d(n,0) ;
    
    vector<int64_t> SubScore(n,0) ;
    calcSubScore(list,d,SubScore,0,-1) ;

    vector<pair<Costs,Costs>> dp(n,make_pair(Costs(-1,0),Costs(-1,0))) ;
    
    solve(list,d,SubScore,dp,0,-1) ;
    
    for (int i = 0; i < n; i++)
    {
        cout << 2*(n-1) - dp.at(i).first.cost << endl ;
    }
    
}
accuracy: 1
time_ms: 70
memory_kb: 27508
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(a) (a).begin(), (a).end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n); i >= 0; i--)
#define range(i, l, r) for (int i = (int)(l); i < (int)(r); i++)
using ll = long long;

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    os << "[";
    for (int i = 0; i < v.size(); i++) {
        os << v[i] << (i == (v.size() - 1) ? "" : ", ");
    }
    os << "]";
    return os;
}

template <typename T1, typename T2>
ostream& operator<<(ostream& os, const pair<T1, T2> p) {
    os << "{" << p.first << ", " << p.second << "}";
    return os;
}

int n;
vector<int> dist, ans;
vector<vector<int>> edges;
void dfs1(int i, int p) {
    dist[i] = 0;
    for (auto j : edges[i])
        if (j != p) {
            dfs1(j, i);
            dist[i] = max(dist[j] + 1, dist[i]);
        }
}

void dfs2(int i, int p, int pd) {
    vector<pair<int, int>> dp;
    for (auto j : edges[i]) {
        if (j == p) {
            dp.push_back({pd, j});
        } else {
            dp.push_back({dist[j], j});
        }
    }
    dp.push_back({-1, -1});
    sort(all(dp));
    reverse(all(dp));
    ans[i] = dp[0].first + 1;

    for (auto j : edges[i]) {
        if (j == p) continue;
        if (dp[0].second == j) {
            dfs2(j, i, dp[1].first + 1);
        } else {
            dfs2(j, i, dp[0].first + 1);
        }
    }
}

int main() {
    cin >> n;
    ans.resize(n);
    edges.resize(n);
    dist.resize(n);
    rep(i, n - 1) {
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edges[u].push_back(v);
        edges[v].push_back(u);
    }

    dfs1(0, -1);
    dfs2(0, -1, -1);
    rep(i, n) cout << 2 * (n - 1) - ans[i] << endl;
}
accuracy: 1
time_ms: 110
memory_kb: 28052
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(a) (a).begin(), (a).end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n); i >= 0; i--)
#define range(i, l, r) for (int i = (int)(l); i < (int)(r); i++)
using ll = long long;

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    os << "[";
    for (int i = 0; i < v.size(); i++) {
        os << v[i] << (i == (v.size() - 1) ? "" : ", ");
    }
    os << "]";
    return os;
}

template <typename T1, typename T2>
ostream& operator<<(ostream& os, const pair<T1, T2> p) {
    os << "{" << p.first << ", " << p.second << "}";
    return os;
}

int n;
vector<int> ans;
void dfs(int i, vector<vector<int>>& edges, vector<int>& par,
         vector<vector<pair<int, int>>>& dp1, vector<int>& dp2) {
    ans[i] = 2 * (n - 1) - dp2[i];
    for (auto j : edges[i]) {
        if (j != par[i]) {
            if (dp2[i] > 0 && dp1[i][0].second == j) {
                if (dp1[i].size() > 1) {
                    dp2[i] = dp1[i][1].first + 1;
                } else {
                    dp2[i] = 0;
                }
            }
            dp1[j].push_back({dp2[i], i});
            sort(all(dp1[j]));
            reverse(all(dp1[j]));
            dp2[j] = dp1[j][0].first + 1;
            dfs(j, edges, par, dp1, dp2);

            dp2[i] = dp1[i][0].first + 1;
        }
    }
}

int main() {
    cin >> n;
    ans.resize(n);
    vector<vector<int>> edges(n);
    rep(i, n - 1) {
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edges[u].push_back(v);
        edges[v].push_back(u);
    }

    vector<vector<pair<int, int>>> dp1(n);
    vector<int> dp2(n, -1);
    vector<int> q{~0, 0};
    vector<int> par(n, -1);
    while (!q.empty()) {
        int i = q.back();
        q.pop_back();
        if (i >= 0) {
            for (auto j : edges[i])
                if (j != par[i]) {
                    par[j] = i;
                    q.push_back(~j);
                    q.push_back(j);
                }
        } else {
            i = ~i;
            for (auto j : edges[i])
                if (j != par[i]) {
                    dp1[i].push_back({dp2[j], j});
                }
            sort(all(dp1[i]));
            reverse(all(dp1[i]));
            if (dp1[i].size() > 0) {
                dp2[i] = dp1[i][0].first + 1;
            } else {
                dp2[i] = 0;
            }
        }
    }

    dfs(0, edges, par, dp1, dp2);
    rep(i, n) cout << ans[i] << endl;
}
accuracy: 1
time_ms: 120
memory_kb: 29760
final_rank: 13

code_snippet: #ifndef ONLINE_JUDGE
#define _GLIBCXX_DEBUG //[]で配列外参照をするとエラーにしてくれる。上下のやつがないとTLEになるので注意 ABC311Eのサンプル4みたいなデバック中のTLEは防げないので注意
#endif
#include <bits/stdc++.h>

// #include <atcoder/all>
// using namespace atcoder;

using namespace std;
using ll = long long;
ll INF = 2e18;
using P = pair<ll, ll>;
#define pb push_back
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define reprev(i, n) for (ll i = (n) - 1; i >= 0; i--)
#define reps(i, n) for (ll i = 1; i <= (n); i++)
#define for_(i, a, b) for (ll i = (a); i < (b); i++)
#define all(v) v.begin(), v.end()
template <typename T>
inline bool chmin(T &a, const T &b)
{
  bool c = a > b;
  if (c)
    a = b;
  return c;
}
template <typename T>
inline bool chmax(T &a, const T &b)
{
  bool c = a < b;
  if (c)
    a = b;
  return c;
}
template <typename T>
inline T ceil(T a, T b) { return (a + (b - 1)) / b; }
// using mint = modint998244353;
//  using mint = modint1000000007;
//  using mint = static_modint<10>;//使うときはコメントアウトを外す
template <typename T>
using vc = vector<T>;
template <class T>
istream &operator>>(istream &i, vc<T> &v)
{
  rep(j, size(v)) i >> v[j];
  return i;
}
template <class T>
ostream &operator<<(ostream &o, const vc<T> &v)
{
  rep(j, size(v))
  {
    if (j)
      o << " ";
    o << v[j];
  }
  o << endl;
  return o;
}
// ref:https://algo-logic.info/tree-dp/
/* Rerooting: 全方位木 DP
    問題ごとに以下を書き換える
    - 型DPと単位元
    - 型DPに対する二項演算 merge
    - まとめたDPを用いて新たな部分木のDPを計算する add_root
    計算量: O(N)
*/
struct Rerooting
{
  /* start 問題ごとに書き換え */
  struct DP
  { // DP の型
    ll diff;
    ll cycle;
    ll edge_cnt;
    DP(long long diff_ = 0, ll cycle_ = 0, ll cnt = 0) : diff(diff_), cycle(cycle_), edge_cnt(cnt) {}
  };
  const DP identity = DP(); // 単位元(末端の値は add_root(identity) になるので注意)
  function<DP(DP, DP)> merge = [](DP dp_cum, DP d) -> DP
  {
    return DP(max(dp_cum.diff, d.diff), dp_cum.cycle + d.cycle, dp_cum.edge_cnt + d.edge_cnt);
  };
  function<DP(DP)> add_root = [](DP d) -> DP
  {
    if (d.cycle == 0 && d.edge_cnt == 0)
    {
      return DP(0, 0);
    }
    return DP(d.diff + 1, d.cycle + d.edge_cnt * 2, 0);
  };
  /* end 問題ごとに書き換え */
  // グラフの定義
  struct Edge
  {
    int to;
  };
  using Graph = vector<vector<Edge>>;
  vector<vector<DP>> dp; // dp[v][i]: vから出るi番目の有向辺に対応する部分木のDP
  vector<DP> ans;        // ans[v]: 頂点vを根とする木の答え
  Graph G;
  Rerooting(int N) : G(N)
  {
    dp.resize(N);
    ans.assign(N, identity);
  }
  void add_edge(int a, int b)
  {
    G[a].push_back({b});
  }
  void build()
  {
    dfs(0);           // 普通に木DP
    bfs(0, identity); // 残りの部分木に対応するDPを計算
  }
  DP dfs(int v, int p = -1)
  { // 頂点v, 親p
    DP dp_cum = identity;
    int deg = G[v].size();
    dp[v] = vector<DP>(deg, identity);
    ll cnt = 0;
    for (int i = 0; i < deg; i++)
    {
      int u = G[v][i].to;
      if (u == p)
        continue;
      cnt++;
      dp[v][i] = dfs(u, v);
      dp_cum = merge(dp_cum, dp[v][i]);
      // dp_cum = merge(dp_cum, DP(dp[v][i].dp + G[v][i].cost));
    }
    dp_cum.edge_cnt = cnt;
    return add_root(dp_cum);
  }
  void bfs(int v, const DP &dp_p, int p = -1)
  { // bfs だが、実装が楽なので中身は dfs になっている
    int deg = G[v].size();
    for (int i = 0; i < deg; i++)
    { // 前のbfsで計算した有向辺に対応する部分木のDPを保存
      if (G[v][i].to == p)
        dp[v][i] = dp_p;
    }
    vector<DP> dp_l(deg + 1, identity), dp_r(deg + 1, identity); // 累積merge
    for (int i = 0; i < deg; i++)
    {
      dp_l[i + 1] = merge(dp_l[i], dp[v][i]);
      dp_l[i + 1].edge_cnt++;
      // dp_l[i + 1] = merge(dp_l[i], DP(dp[v][i].dp + G[v][i].cost));
    }
    for (int i = deg - 1; i >= 0; i--)
    {
      dp_r[i] = merge(dp_r[i + 1], dp[v][i]);
      dp_r[i].edge_cnt++;
      // dp_r[i] = merge(dp_r[i + 1], DP(dp[v][i].dp + G[v][i].cost));
    }
    ans[v] = add_root(dp_l[deg]); // 頂点 v の答え
    for (int i = 0; i < deg; i++)
    { // 一つ隣の頂点に対しても同様に計算
      int u = G[v][i].to;
      if (u == p)
        continue;

      bfs(u, add_root(merge(dp_l[i], dp_r[i + 1])), v);
    }
  }
};
int main()
{
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  // ref:https://rsk0315.hatenablog.com/entry/2020/05/09/170315
  ll N;
  cin >> N;
  Rerooting reroot(N);
  rep(i, N - 1)
  {
    ll a, b;
    cin >> a >> b;
    reroot.add_edge(a - 1, b - 1);
    reroot.add_edge(b - 1, a - 1);
  }
  reroot.build();
  ll ans = INF;
  rep(i, N)
  {
    cout << reroot.ans[i].cycle - reroot.ans[i].diff << endl;
  }

  //  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 106644
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

#ifdef LOCAL
#include <debug.hpp>
#else
#define debug(...)
#endif

// g[from] contains outgoing edges (to, edgeid(from, to))
// (E, op, e) is commutative monoid
// ~edgeid(from, to) == edgeid(to, from)
// return calculator of dp(r, v)
template <class V, class E>
auto rerootingdp(auto op, E e, auto put_edge, auto put_vertex, const vector<vector<pair<int, int>>>& g, int root = 0) {
    struct dp {
        // dp(r, v) : root is r, dp of subtree v
        // ans[v]  = dp(v, v)
        // from[v] = dp(v, par(v))
        // to[v]   = dp(par(v), v)
        // from[root] and to[root] is undefined
        vector<V> ans, from, to;
        vector<int> down, up;
        vector<vector<int>> childs;
        bool is_in_subtree(int r, int v) { return down[r] < down[v] && up[v] <= up[r]; }
        V operator()(int r, int v) {
            if (r == v) return ans[v];
            if (!is_in_subtree(v, r)) return to[v];
            int left = 0, right = ssize(childs[v]);
            while (right - left > 1) {
                int mid = midpoint(left, right);
                (down[childs[v][mid]] <= down[r] ? left : right) = mid;
            }
            return from[childs[v][left]];
        }
    };
    // 根を root としたときの dp の値を計算
    int n = ssize(g);
    vector<E> from(n, e), to(n, e);
    vector<V> dp_to(n);
    vector<vector<int>> childs(n);
    vector<int> down(n), up(n);
    int t = 0;
    auto dfs1 = [&](auto&& self, int v, int p) -> void {
        down[v] = t++;
        childs[v].reserve(g[v].size());
        for (auto [c, eid] : g[v]) {
            if (c == p) continue;
            childs[v].emplace_back(c);
            self(self, c, v);
            // to[c] に頂点 c の情報を加えたもの
            dp_to[c] = put_vertex(to[c], c);
            to[c] = put_edge(dp_to[c], eid);
            to[v] = op(to[v], to[c]);
        }
        up[v] = t;
    };
    dfs1(dfs1, root, -1);

    vector<V> dp_ans(n), dp_from(n);
    // tail[i] := 頂点 v の子の辺に対し, 右側から蓄積した dp の値
    vector<E> tail(n);
    auto dfs2 = [&](auto&& self, int v, int p) -> void {
        tail[ssize(g[v])] = e;
        int cur = ssize(g[v]) - 1;
        for (auto [c, eid] : g[v] | views::reverse) {
            if (c == p) continue;
            tail[cur] = op(tail[cur + 1], to[c]);
            cur--;
        }
        dp_ans[v] = put_vertex(op(tail[++cur], from[v]), v);
        E acc = e;
        for (auto [c, eid] : g[v]) {
            if (c == p) continue;
            dp_from[c] = put_vertex(op(op(acc, tail[++cur]), from[v]), v);
            from[c] = put_edge(dp_from[c], ~eid);
            acc = op(acc, to[c]);
        }
        for (auto [c, eid] : g[v]) {
            if (c == p) continue;
            self(self, c, v);
        }
    };
    dfs2(dfs2, root, -1);
    return dp{dp_ans, dp_from, dp_to, down, up, childs};
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    int N;
    cin >> N;
    vector<vector<pair<int, int>>> G(N);
    for (int i = 0; i < N - 1; i++) {
        int u, v;
        cin >> u >> v, u--, v--;
        G[u].emplace_back(v, i);
        G[v].emplace_back(u, ~i);
    }

    // まずは普通の木 dp を考える
    // dp[i] := i をスタートして, その部分木に含まれる頂点を訪れて戻るまでの最短距離
    // vector<int> dp(N), height(N);
    // auto dfs = [&](auto&& self, int v, int p) -> void {
    //     int _dp = 0, _height = 0;
    //     for (auto [c, eid] : G[v]) {
    //         if (c == p) continue;
    //         self(self, c, v);
    //         _dp += dp[c] + 2;
    //         _height = max(_height, height[c] + 1);
    //     }
    //     dp[v] = _dp;
    //     height[v] = _height;
    // };

    // for (int i = 0; i < N; i++) {
    //     dp.assign(N, 0);
    //     dfs(dfs, i, -1);
    //     // dp[i] - height[i] が答え
    //     cout << dp[i] - height[i] << '\n';
    // }

    // 全方位木 dp
    using T = pair<int, int>;
    auto op = [](T a, T b) { return T{a.first + b.first, max(a.second, b.second)}; };
    T e = T{0, 0};
    auto put_edge = [](T v, int) { return T{v.first + 2, v.second + 1}; };
    auto put_vertex = [](T v, int) { return v; };

    auto dp = rerootingdp<T, T>(op, e, put_edge, put_vertex, G);
    for (int i = 0; i < N; i++) {
        debug(dp(i, i));
        cout << dp(i, i).first - dp(i, i).second << '\n';
    }
}
accuracy: 1
time_ms: 30
memory_kb: 39380
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
int main() {
  int N;
  cin >> N;
  vector E(N, vector<int>());
  for (int i = 0; i < N - 1; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    E[u].push_back(v);
    E[v].push_back(u);
  }
  vector<int> dp1(N, 0);
  auto dfs1 = [&] (auto dfs1, int v, int p) -> void {
    for (int w : E[v]) {
      if (w != p) {
        dfs1(dfs1, w, v);
        dp1[v] = max(dp1[v], dp1[w] + 1);
      }
    }
  };
  dfs1(dfs1, 0, -1);
  vector<int> dp2(N, 0);
  vector<int> ans(N);
  auto dfs2 = [&] (auto dfs2, int v, int p) -> void {
    vector<pair<int, int>> A;//(葉までの距離, 頂点)
    A.emplace_back(0, -1);
    for (int w : E[v]) {
      if (w != p) {
        A.emplace_back(dp1[w] + 1, w);
      } else {
        A.emplace_back(dp2[v] + 1, w);
      }
    }
    sort(A.rbegin(), A.rend());
    ans[v] = A[0].first;
    for (int w : E[v]) {
      if (w != p) {
        if (A[0].second == w) {
          dp2[w] = A[1].first;
        } else {
          dp2[w] = A[0].first;
        }
        dfs2(dfs2, w, v);
      }
    }
  };
  dfs2(dfs2, 0, -1);
  for (int i = 0; i < N; i++) {
    cout << (N - 1) * 2 - ans[i] << '\n';
  }
}
accuracy: 1
time_ms: 40
memory_kb: 31860
final_rank: 3

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

int N;
vector<int> G[1<<17];
vector<int> dp[1<<17];
int ans[1<<17];

void pG(){
	for(int i=0;i<N;i++){
		cout<<i<<":";
		for(int j=0;j<G[i].size();j++){
			cout<<G[i][j]<<" ";
		}
		cout<<endl;
	}
	cout<<endl;
}

void pdp(){
	for(int i=0;i<N;i++){
		cout<<i<<":";
		for(int j=0;j<dp[i].size();j++){
			cout<<dp[i][j]<<" ";
		}
		cout<<endl;
	}
	cout<<endl;
}

int rec(int v, int p=-1){
	int s=G[v].size();
	int res=0;
	dp[v].assign(s,-1);
	for(int i=0;i<s;i++){
		int to=G[v][i];
		if(to!=p){
			dp[v][i]=rec(to,v);
			res=max(res,dp[v][i]+1);
		}
	}
	return res;
}

void rerec(int v,int pval,int p){
	int s=G[v].size();
	//pdp();
	for(int i=0;i<s;i++){
		int to=G[v][i];
		if(to==p){
			dp[v][i]=pval;
		}
	}
	vector<int> left(s+1,-1),right(s+1,-1);
	for(int i=0;i<s;i++){
		left[i+1]=max(left[i],dp[v][i]);
		right[i+1]=max(right[i],dp[v][s-i-1]);
	}
	for(int i=0;i<s;i++){
		int to=G[v][i];
		if(to!=p){
			rerec(to, max(left[i],right[s-i-1])+1,v);
		}
	}
}

void solve(){
	rec(0,-1);
	rerec(0,0,-1);
	//pdp();
	for(int v=0;v<N;v++){
		int res=0;
		for(int i=0;i<G[v].size();i++){
			res=max(res,dp[v][i]+1);
		}
		cout<<(N-1)*2-res<<endl;
	}
}

int main(){
	cin>>N;
	for(int i=0;i<N-1;i++){
		int u,v;
		cin>>u>>v;
		u--,v--;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	solve();
}
accuracy: 1
time_ms: 120
memory_kb: 31216
final_rank: 14

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

vector<int> G[1<<17];
int dp[1<<17];
int ans[1<<17];

void dfs(int idx,int par){
	for(auto &n:G[idx])if(n!=par){
		dfs(n,idx);
		dp[idx]=max(dp[idx],dp[n]+1);
	}
}

void dfs2(int idx,int d_par,int par){
	vector<pair<int,int>> d_child;
	d_child.emplace_back(0,-1);
	for(auto &n:G[idx]){
		if(n==par)d_child.emplace_back(d_par+1,n);
		else d_child.emplace_back(dp[n]+1,n);
	}
	sort(d_child.rbegin(),d_child.rend());
	ans[idx]=d_child[0].first;
	for(int &n:G[idx])if(n!=par){
		dfs2(n, d_child[d_child[0].second==n].first, idx);
	}
}

int main(){
	int N;
	cin>>N;
	for(int i=0;i<N-1;i++){
		int u,v;
		cin>>u>>v;
		u--,v--;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(0,-1);
	dfs2(0,0,-1);
	for(int i=0;i<N;i++){
		cout<<(N-1)*2-ans[i]<<endl;
	}
}
accuracy: 1
time_ms: 110
memory_kb: 28900
final_rank: 12

code_snippet: // #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;

/* alias*/
using ull = unsigned long long;
using ll = long long;
using vi = vector<int>;
using vl = vector<long long>;
using vs = vector<string>;
using vb = vector<bool>;
using vd = vector<double>;
using vvi = vector<vi>;
using vvl = vector<vl>;
using vvd = vector<vd>;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using vpi = vector<pi>;
using vpl = vector<pl>;
using vvpi = vector<vpi>;
using vvpl = vector<vpl>;

/* define short */
#define _overload5(a, b, c, d, e, name, ...) name
#define _overload4(a, b, c, d, name, ...) name
#define _overload3(a, b, c, name, ...) name
#define _rep0(n) for(int i = 0; i < (int)(n); ++i)
#define _rep1(i, n) for(int i = 0; i < (int)(n); ++i)
#define _rep2(i, a, b) for(int i = (int)(a); i < (int)(b); ++i)
#define _rep3(i, a, b, c) for(int i = (int)(a); i < (int)(b); i += (int)(c))
#define rep(...) _overload4(__VA_ARGS__, _rep3, _rep2, _rep1, _rep0)(__VA_ARGS__)
#define rrep1(n) for(int i = (n) - 1;i >= 0;i--)
#define rrep2(i,n) for(int i = (n) - 1;i >= 0;i--)
#define rrep3(i,a,b) for(int i = (b) - 1;i >= (a);i--)
#define rrep4(i,a,b,c) for(int i = (a) + ((b)-(a)-1) / (c) * (c);i >= (a);i -= c)
#define rrep(...) _overload4(__VA_ARGS__, rrep4, rrep3, rrep2, rrep1)(__VA_ARGS__)
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define sz(x) (int)(x).size()
#define pcnt(x) __builtin_popcountll(x)
#define eb emplace_back
#define fi first
#define se second

/* debug */
// 標準エラー出力を含む提出はrejectされる場合もあるので注意
#define debug(x) cerr << "\033[33m(line:" << __LINE__ << ") " << #x << ": " << x << "\033[m" << endl;

/* func */
template<class T> inline bool chmax(T& a, T b) { return ((a < b) ? (a = b, true) : (false)); }
template<class T> inline bool chmin(T& a, T b) { return ((a > b) ? (a = b, true) : (false)); }

/* const */
const int INF = INT_MAX/2;
const ll LINF = 1LL<<60;
const int MOD = 1e9+7;
const int dx[] {1,0,-1,0};
const int dy[] {0,1,0,-1};
const double PI = 3.1415926535;
const string yes = "Yes";
const string no = "No";


int main() { 
  int n; cin >> n;
  vvi g(n);
  rep(i,n-1) {
    int u, v; cin >> u >> v; u--; v--;
    g[u].eb(v);
    g[v].eb(u);
  }

  vi dist(n);
  auto dfs = [&](auto self, int v, int pv=-1) -> void {
    for (auto nv: g[v]) {
      if (nv == pv) continue;
      self(self,nv,v);
      chmax(dist[v],dist[nv]+1);
    }
  };
  dfs(dfs,0);

  vi ans(n);
  auto rerooting = [&](auto self, int v, int pv=-1, int d_par=0) -> void {
    vpi d_dist; d_dist.eb(-1,-1);
    for (auto nv : g[v]) {
      if (nv == pv) d_dist.eb(d_par+1,nv);
      else d_dist.eb(dist[nv],nv);
    }
    sort(rall(d_dist));
    ans[v] = d_dist[0].fi;

    for (auto nv : g[v]) {
      if (nv == pv) continue;
      int nd_par = (d_dist[0].se == nv ? d_dist[1].fi : d_dist[0].fi);
      self(self,nv,v,nd_par);
    }
  };
  rerooting(rerooting,0);

  rep(v,n) {
    int now = 2*(n-1)-ans[v]-1;
    cout << now << '\n';
  }
  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 31164
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
vector<int> edge[100010];
int dist[100010]={};
void dfs1(int now, int par){
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        dfs1(to, now);
        dist[now] = max(dist[now], 1+dist[to]);
    }
}
int dp[100010]={};
void dfs2(int now, int par, int pval){
    int ma1=pval+1, ma2=0;
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        int nv = dist[to]+1;
        if(ma2<nv){
            swap(nv, ma2);
            if(ma1<ma2) swap(ma1, ma2);
        }
    }
    dp[now] = ma1;
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        if(dist[to]+1==ma1) dfs2(to, now, ma2);
        else dfs2(to, now, ma1);
    }
}
int main(){
    int n, u, v;
    cin >> n;
    for(int i=0;i<n-1;i++){
        cin >> u >> v;
        edge[--u].push_back(--v);
        edge[v].push_back(u);
    }
    dfs1(0, -1);
    dfs2(0, -1, -1);
    for(int i=0;i<n;i++) cout << n+n-2-dp[i] << endl;
    return(0);
}
accuracy: 1
time_ms: 110
memory_kb: 15628
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
vector<int> edge[100010];
int dist[100010]={};
void dfs1(int now, int par){
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        dfs1(to, now);
        dist[now] = max(dist[now], 1+dist[to]);
    }
}
int dp[100010]={};
void dfs2(int now, int par, int pval){
    int ma1=pval+1, ma2=0;
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        int nv = dist[to]+1;
        if(ma2<nv){
            swap(nv, ma2);
            if(ma1<ma2) swap(ma1, ma2);
        }
    }
    dp[now] = ma1;
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        if(dist[to]+1==ma1) swap(ma1, ma2);
        dfs2(to, now, ma1);
    }

}
int main(){
    int n, u, v;
    cin >> n;
    for(int i=0;i<n-1;i++){
        cin >> u >> v;
        u--;
        v--;
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    dfs1(0, -1);
    dfs2(0, -1, -1);
    for(int i=0;i<n;i++) cout << n+n-2-dp[i] << endl;
    return(0);
}
accuracy: 0.125
time_ms: 110
memory_kb: 9888
final_rank: 19

code_snippet: #include<bits/stdc++.h>
using namespace std;
vector<int> edge[100010];
int dist[100010]={};
void dfs1(int now, int par){
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        dfs1(to, now);
        dist[now] = max(dist[now], 1+dist[to]);
    }
}
int dp[100010]={};
void dfs2(int now, int par, int pval){
    int ma1=pval+1, ma2=0;
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        int nv = dist[to]+1;
        if(ma2<nv){
            swap(nv, ma2);
            if(ma1<ma2) swap(ma1, ma2);
        }
    }
    dp[now] = ma1;
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        if(dist[to]+1==ma1) swap(ma1, ma2);
        dfs2(to, now, ma1);
    }

}
int main(){
    int n, u, v;
    cin >> n;
    for(int i=0;i<n-1;i++){
        cin >> u >> v;
        edge[--u].push_back(--v);
        edge[v].push_back(u);
    }
    dfs1(0, -1);
    dfs2(0, -1, -1);
    for(int i=0;i<n;i++) cout << n+n-2-dp[i] << endl;
    return(0);
}
accuracy: 0.125
time_ms: 110
memory_kb: 9892
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;
vector<int> edge[100010];
int dp[100010]={};
int dist[100010]={};
void dfs1(int now, int par){
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        dfs1(to, now);
        dist[now] = max(dist[now], dist[to]+1);
    }
}
void dfs2(int now, int par, int pval){
    int ma1=pval+1, ma2=0;
    for(int i=0;i<edge[now].size();i++){
        int to=edge[now][i];
        if(to==par) continue;
        int nv = dist[to]+1;
        if(ma2<=nv){
            swap(nv, ma2);
            if(ma1<ma2) swap(ma1, ma2);
        }
    }
    dp[now] = ma1;
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        if(dist[to]+1==ma1) swap(ma1, ma2);
        dfs2(to, now, ma1);
    }
}
int main(){
    int n, u, v;
    cin >> n;
    for(int i=0;i<n-1;i++){
        cin >> u >> v;
        edge[--u].push_back(--v);
        edge[v].push_back(u);
    }
    dfs1(0, -1);
    dfs2(0, -1, -1);
    for(int i=0;i<n;i++) cout << n+n-2-dp[i] << endl;
    return(0);
}
accuracy: 0.125
time_ms: 110
memory_kb: 9820
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
vector<int> edge[100010];
int dp[100010], dist[100010]={};
void dfs1(int now, int par){
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        dfs1(to, now);
        dist[now] = max(dist[now], dist[to]+1);
    }
}
void dfs2(int now, int par, int pval){
    int ma1=pval+1, ma2=0;
    for(int i=0;i<edge[now].size();i++){
        int to=edge[now][i], nv = dist[to]+1;
        if(to==par) continue;
        if(ma2<=dist[to]){
            swap(nv, ma2);
            if(ma1<ma2) swap(ma1, ma2);
        }
    }
    dp[now] = ma1;
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        if(dist[to]+1==ma1) swap(ma1, ma2);
        dfs2(to, now, ma1);
    }
}
int main(){
    int n, u, v;
    cin >> n;
    for(int i=0;i<n-1;i++){
        cin >> u >> v;
        edge[--u].push_back(--v);
        edge[v].push_back(u);
    }
    dfs1(0, -1);
    dfs2(0, -1, -1);
    for(int i=0;i<n;i++) cout << n+n-2-dp[i] << endl;
    return(0);
}
accuracy: 0.125
time_ms: 100
memory_kb: 9892
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<int> edge[100010];
ll dist[100010]={};
void dfs1(int now, int par){
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        dfs1(to, now);
        dist[now] = max(dist[now], 1+dist[to]);
    }
}
ll dp[100010]={};
void dfs2(int now, int par, int pval){
    int ma1=pval+1, ma2=0;
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        int nv = dist[to]+1;
        if(ma2<nv){
            swap(nv, ma2);
            if(ma1<ma2) swap(ma1, ma2);
        }
    }

    dp[now] = ma1;
    for(int i=0;i<edge[now].size();i++){
        int to = edge[now][i];
        if(to==par) continue;
        if(dist[to]+1==ma1) dfs2(to, now, ma2);
        else dfs2(to, now, ma1);
    }

}

int main(){
    int n, u, v;
    cin >> n;
    for(int i=0;i<n-1;i++){
        cin >> u >> v;
        u--;
        v--;
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    dfs1(0, -1);
    dfs2(0, -1, -1);
    for(int i=0;i<n;i++) cout << n+n-2-dp[i] << endl;
    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 18280
final_rank: 9

code_snippet: #line 1 "/home/dispersion/competitive/icpc/ICPC-library/ICPC2024/merge_src_docs/template/24_template.hpp"
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
#define rep(i, n) for(ll i = 0; i < n; i++)
#define rep2(i, l, r) for(ll i = l; i < r; i++)

using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;

#define all(A) A.begin(), A.end()
#define elif else if
using pii = pair<ll, ll>;

bool chmin(auto &a, auto b) { return a > b ? a = b, 1 : 0; }
bool chmax(auto &a, auto b) { return a < b ? a = b, 1 : 0; }

struct IOSetup {
  IOSetup() {
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
} iosetup;

template<class T>
void print(vector<T> a) {
  for(auto x : a) cout << x << ' ';
  cout << endl;
}

void print(auto x) { cout << x << endl; }

template<class Head, class... Tail>
void print(Head &&head, Tail &&...tail) {
  cout << head << ' ';
  print(forward<Tail>(tail)...);
}
#line 2 "Rerooting.cpp"

using S = ll;

int n;
vector<vector<pair<int, int>>> edge;

vector<S> dp1, dp2, ans;
S e() {return 0LL;}
S f(S res, int i) {return res + 1;}
S g(S res, int v) {return res;}
S merge(S a, S b) {return max(a, b);}

void dfs1(int v, int p) {
  for(auto [u, id] : edge[v]) {
    if(u != p) {
      dfs1(u, v);
      dp1[v] = merge(dp1[v], f(dp1[u], id));
    }
  }
  dp1[v] = g(dp1[v], v);
}

void dfs2(int v, int p) {
  int s = edge[v].size();
  vector<S> R(s + 1, e());
  for(int i = s - 1; i >= 0; i--) {
    auto [u, id] = edge[v][i];
    if(u == p) R[i] = merge(R[i + 1], f(dp2[v], id));
    else R[i] = merge(R[i + 1], f(dp1[u], id));
  }

  S L = e();
  rep(i, s) {
    auto [u, id] = edge[v][i];
    if(u != p) {
      dp2[u] = g(merge(L, R[i + 1]), v);
      L = merge(L, f(dp1[u], id));
      dfs2(u, v);
    }
    else { L = merge(L, f(dp2[v], id)); }
  }
  ans[v] = g(L, v);
}

// https://onlinejudge.u-aizu.ac.jp/services/ice/?problemId=1595
void solve1() {
  ll N; cin >> N;
  dp1.assign(N, e());
  dp2.assign(N, e());
  ans.resize(N);
  edge.assign(N, vector<pair<int, int>>());
  ll edge_id = 0;
  rep(i, N-1) {
    ll u, v; cin >> u >> v;
    u--, v--;
    edge[u].push_back({v, edge_id++});
    edge[v].push_back({u, edge_id++});
  }
  
  dfs1(0, -1);
  dfs2(0, -1);
  
  rep(i, N) {
    ll res = 2 * (N-1) - ans[i];
    cout << res << '\n';
  }
  
  return;
}

int main() {
  solve1();
  
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 23680
final_rank: 1

code_snippet: // 参考 https://algo-logic.info/tree-dp/

#include <bits/stdc++.h>
using namespace std;

/* Rerooting: 全方位木 DP
    問題ごとに以下を書き換える
    - 型DPと単位元
    - 型DPに対する二項演算 merge
    - まとめたDPを用いて新たな部分木のDPを計算する add_root
    計算量: O(N)
*/

// グラフの定義
struct Edge {
    int to;
    long long w;
};
using Graph = vector<vector<Edge>>;

struct Rerooting {
    /* start 問題ごとに書き換え */
    struct DP {  // DP の型
        long long dp;
    };
    const DP identity = DP{0};  // 単位元(末端の値は add_root(identity) になるので注意)
    DP connect(DP d, Edge e){
        return DP{d.dp + e.w};
    }
    DP merge(DP dp_cum, DP d){
        return DP{max(dp_cum.dp, d.dp)};
    }
    DP add_root(DP d){
        return DP{d.dp};
    }
    /* end 問題ごとに書き換え */

    vector<vector<DP>> dp;  // dp[v][i]: vから出るi番目の有向辺に対応する部分木のDP
    vector<DP> ans;         // ans[v]: 頂点vを根とする木の答え
    Graph G;

    Rerooting(int N){
        G.resize(N);
        dp.resize(N);
        ans.assign(N, identity);
    }

    void add_edge(int a, Edge e) {
        G[a].push_back(e);
    }
    void build() {
        dfs(0);            // 普通に木DP
        bfs(0, identity);  // 残りの部分木に対応するDPを計算
    }

    DP dfs(int v, int p = -1) {  // 頂点v, 親p
        DP dp_cum = identity;
        int deg = G[v].size();
        dp[v] = vector<DP>(deg, identity);
        for (int i = 0; i < deg; i++) {
            int u = G[v][i].to;
            if (u == p) continue;
            dp[v][i] = dfs(u, v);
            dp_cum = merge(dp_cum, connect(dp[v][i], G[v][i]));
        }
        return add_root(dp_cum);
    }
    void bfs(int v, const DP& dp_p, int p = -1) {  // bfs だが、実装が楽なので中身は dfs になっている
        int deg = G[v].size();
        for (int i = 0; i < deg; i++) {  // 前のbfsで計算した有向辺に対応する部分木のDPを保存
            if (G[v][i].to == p) dp[v][i] = dp_p;
        }
        vector<DP> dp_l(deg + 1, identity), dp_r(deg + 1, identity);  // 累積merge
        for (int i = 0; i < deg; i++) {
            dp_l[i + 1] = merge(dp_l[i], connect(dp[v][i], G[v][i]));
        }
        for (int i = deg - 1; i >= 0; i--) {
            dp_r[i] = merge(dp_r[i + 1], connect(dp[v][i], G[v][i]));
        }

        ans[v] = add_root(dp_l[deg]);  // 頂点 v の答え

        for (int i = 0; i < deg; i++) {  // 一つ隣の頂点に対しても同様に計算
            int u = G[v][i].to;
            if (u == p) continue;
            bfs(u, add_root(merge(dp_l[i], dp_r[i + 1])), v);
        }
    }
};

int main(){
  int N; cin>>N;
  Rerooting reroot(N);
  for(int i=0;i<N-1;i++){
    int s,t; cin>>s>>t; s--; t--;
    reroot.add_edge(s,Edge{t,1});
    reroot.add_edge(t,Edge{s,1});
  }
  reroot.build();
  for(int i=0;i<N;i++){
    cout<<2*(N-1)-reroot.ans[i].dp<<endl;
  }
}
accuracy: 1
time_ms: 120
memory_kb: 33396
final_rank: 15