Bzoj-1131 Sta [DFS]

1131: [POI2008]Sta

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1629  Solved: 611
[Submit][Status][Discuss]

Description

给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大

Input

给出一个数字N,代表有N个点.N<=1000000 下面N-1条边.

Output

输出你所找到的点,如果具有多个解,请输出编号最小的那个.

Sample Input

8
1 4
5 6
4 5
6 7
6 8
2 4
3 4

Sample Output

7

HINT

Source

[Submit][Status][Discuss]

比较简单的一题
当我们在u点时   假设u为根的树深度和为X  那么向u的子节点v走一步后  u及u的祖先和v的兄弟等所有不属于v所在子树的节点的深度都+1   而v所在子树的所有点包括v的深度都-1  所以X变成了  X = X + (n - siz[v]) - siz[v]
所以两次DFS就可以出答案了
防爆栈写了BFS  但其实旁边的大佬用DFS也A了


/**************************************************************
    Problem: 1131
    User: 
    Language: C++
    Result: Accepted
    Time:6760 ms
    Memory:44264 kb
****************************************************************/
 
#include <bits/stdc++.h>
using namespace std;
 
const int N = 1e6 + 137;
 
inline void read( int &res )
{
    char ch = getchar(); res = 0;
    while(ch < '0' || ch > '9') ch = getchar();
    while(ch >= '0' && ch <= '9') res = res * 10 + ch - 48, ch = getchar();
}
 
int n, head[N], top;
 
struct Node
{
    int y, nxt;
    Node() {    }
    Node( int y, int nxt ) : y(y), nxt(nxt) {   }
} e[N << 1];
 
inline void Adde( int x, int y )
{
    e[++top] = Node(y, head[x]), head[x] = top;
    e[++top] = Node(x, head[y]), head[y] = top;
}
 
int que[N], h, t, fa[N], siz[N], dep[N];
 
void Bfs()
{
    que[++t] = 1;
    fa[1] = 0;
    dep[1] = 0;
    while(h < t)
    {
        int u = que[++h];
        siz[u] = 1;
        for(int i = head[u]; i; i = e[i].nxt)
        {
            int v = e[i].y;
            if(v == fa[u]) continue;
            fa[v] = u;
            dep[v] = dep[u] + 1;
            que[++t] = v;
        }
    }
    for(int i = t; i >= 1; --i)
        for(int j = head[que[i]]; j; j = e[j].nxt)
            if(e[j].y != fa[que[i]]) siz[que[i]] += siz[e[j].y];
}
 
long long f[N], ans = 0, pos;
 
void Bfs1()
{
    h = t = 0;
    que[++t] = 1;
    for(int i = 1; i <= n; ++i) f[1] += dep[i];
    ans = f[1];
    pos = 1;
    while(h < t)
    {
        int u = que[++h];
        for(int i = head[u]; i; i = e[i].nxt)
        {
            int v = e[i].y;
            if(v == fa[u]) continue;
            f[v] = f[u] + (n - siz[v]) - siz[v];
            if(f[v] > ans || (f[v] == ans && pos > v))
                ans = f[v], pos = v;
            que[++t] = v;
        }
    }
}
 
int main()
{
    read(n);
    for(int i = 1, u, v; i < n; ++i)
        read(u), read(v), Adde(u, v);
    Bfs();
    Bfs1();
    cout << pos << endl;
    return 0;
}
/*
8
1 4
5 6
4 5
6 7
6 8
2 4
3 4
*/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值