• 51 nod 1405 树的距离之和


    1405 树的距离之和

    基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
     
    给定一棵无根树,假设它有n个节点,节点编号从1到n, 求任意两点之间的距离(最短路径)之和。
    Input
    第一行包含一个正整数n (n <= 100000),表示节点个数。
    后面(n - 1)行,每行两个整数表示树的边。
    Output
    每行一个整数,第i(i = 1,2,...n)行表示所有节点到第i个点的距离之和。
    Input示例
    4
    1 2
    3 2
    4 2
    Output示例
    5
    3
    5
    5
    /*
    51 nod 1405 树的距离之和
    
    problem:
    给定一棵无根树,假设它有n个节点,节点编号从1到n, 对于每个i求所有点到i的和。
    
    solve:
    假设已经知道了所有点到u的和, 对于它右儿子v的和,可以发现增加了Size[左子树]条uv边.减少了Size[v]条uv边
    所以先求出所有点到1的和,然后可以推出其它所有点
    
    hhh-2016/09/13-20:15:59
    */
    #pragma comment(linker,"/STACK:124000000,124000000")
    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <math.h>
    #include <queue>
    #include <set>
    #include <map>
    #define lson  i<<1
    #define rson  i<<1|1
    #define ll long long
    #define clr(a,b) memset(a,b,sizeof(a))
    #define scanfi(a) scanf("%d",&a)
    #define scanfs(a) scanf("%s",a)
    #define scanfl(a) scanf("%I64d",&a)
    #define scanfd(a) scanf("%lf",&a)
    #define key_val ch[ch[root][1]][0]
    #define eps 1e-7
    #define inf 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const int maxn = 100110;
    
    template<class T> void read(T&num)
    {
        char CH;
        bool F=false;
        for(CH=getchar(); CH<'0'||CH>'9'; F= CH=='-',CH=getchar());
        for(num=0; CH>='0'&&CH<='9'; num=num*10+CH-'0',CH=getchar());
        F && (num=-num);
    }
    int stk[70], tp;
    template<class T> inline void print(T p)
    {
        if(!p)
        {
            puts("0");
            return;
        }
        while(p) stk[++ tp] = p%10, p/=10;
        while(tp) putchar(stk[tp--] + '0');
        putchar('
    ');
    }
    
    ll ans[maxn];
    struct node
    {
        int to,next;
    }edge[maxn <<2];
    
    int tot,n;
    int head[maxn];
    int Size[maxn];
    ll f[maxn];
    void add_edge(int u,int v)
    {
        edge[tot].to = v,edge[tot].next = head[u],head[u] = tot ++;
    }
    
    void dfs(int u,ll len,int pre)
    {
        f[u] = len;
        Size[u] = 1;
        for(int i = head[u]; i != -1;i = edge[i].next )
        {
            int v = edge[i].to;
            if(v == pre)
                continue;
            dfs(v,len+1,u);
            Size[u] += Size[v];
        }
    }
    
    void solve(int u,ll tans,int pre)
    {
        ans[u] = tans;
        for(int i = head[u];i != -1;i = edge[i].next)
        {
            int v = edge[i].to;
            if(v == pre)
                continue;
            ll t = n-Size[v]*2;
            solve(v, (ll)tans + t,u);
        }
    }
    
    void init()
    {
        tot = 0;
        clr(head,-1);
    }
    
    int main()
    {
        int u,v;
        while(scanfi(n) != EOF)
        {
            init();
            for(int i = 1;i < n;i++)
            {
                scanfi(u),scanfi(v);
                add_edge(u,v);
                add_edge(v,u);
            }
            dfs(1,0,-1);
            ll ta = 0;
            for(int i =1;i <= n;i++)
              ta += f[i];
            solve(1,ta,-1);
            for(int i = 1;i <= n;i++)
            {
                print(ans[i]);
            }
        }
    }
    

      

  • 相关阅读:
    数据结构
    java web
    C++
    SQL(结构化查询语言)
    网站协议
    python
    爬虫
    select 多选
    List 去除重复数据的五种方式
    oracle锁表SID查询
  • 原文地址:https://www.cnblogs.com/Przz/p/5869667.html
Copyright © 2020-2023  润新知