zoukankan      html  css  js  c++  java
  • 【树形结构】LG P2052 [NOI2011]道路修建

    题目描述
    
    在 W 星球上有 n 个国家。为了各自国家的经济发展,他们决定在各个国家 之间建设双向道路使得国家之间连通。但是每个国家的国王都很吝啬,他们只愿 意修建恰好 n – 1 条双向道路。 每条道路的修建都要付出一定的费用,这个费用等于道路长度乘以道路两端 的国家个数之差的绝对值。例如,在下图中,虚线所示道路两端分别有 2 个、4 个国家,如果该道路长度为 1,则费用为 1×|24|=2。图中圆圈里的数字表示国 家的编号。 
    
    由于国家的数量十分庞大,道路的建造方案有很多种,同时每种方案的修建 费用难以用人工计算,国王们决定找人设计一个软件,对于给定的建造方案,计 算出所需要的费用。请你帮助国王们设计一个这样的软件。
    
    输入输出格式
    
    输入格式:
    输入的第一行包含一个整数 n,表示 W 星球上的国家的数量,国家从 1 到 n 编号。 接下来 n – 1 行描述道路建设情况,其中第 i 行包含三个整数 ai、bi和 ci,表 示第 i 条双向道路修建在 ai与 bi两个国家之间,长度为 ci。
    
    输出格式:
    输出一个整数,表示修建所有道路所需要的总费用。
    
    输入输出样例
    
    输入样例#1: 复制
    6
    1 2 1
    1 3 1
    1 4 2
    6 3 1
    5 2 1
    输出样例#1: 复制
    20
    说明
    
    1≤ai, bi≤n
    
    0≤ci≤10^6
    
    2≤n≤10^6
    T

    这是一道国赛真·水题

    这道题的思路就没必要讲了,讲两个要注意的地方

    1.宏定义不要随便玩!!!,宏定义的原理是直接替换,所以有些地方会出问题,我被卡了好久

    2.longlong开不彻底的后果是什么?int*longlong可能死不了,但是int-longlong一定会死的!所以要么开彻底,要么运算时候进行强制转换,否则会死的很惨QAQ

    再附一个更新子树节点数量的一般写法

     1 int dfs(int now,int fa)
     2 {
     3     for(int i=head[now];i!=-1;i=edge[i].nxt)
     4     {
     5         int to=edge[i].to;
     6         if(to==fa)continue;
     7         cou[now]+=dfs(to,now);
     8     }
     9     return cou[now];
    10 }

    代码在此

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define N 1000011
     5 #define ll long long
     6 inline ll abs(ll a){return a<0?-a:a;}
     7 int n,u,v,w,cnt=1;
     8 int head[N],cou[N];
     9 struct star{int to,nxt,val;}edge[2*N];
    10 inline void add(int u,int v,int w)
    11     {edge[cnt].nxt=head[u];
    12     edge[cnt].val=w;
    13     edge[cnt].to=v;
    14     head[u]=cnt++;}
    15 int dfs(int now,int fa)
    16 {
    17     for(int i=head[now];i!=-1;i=edge[i].nxt)
    18     {
    19         int to=edge[i].to;
    20         if(to==fa)continue;
    21         cou[now]+=dfs(to,now);
    22     }
    23     return cou[now];
    24 }
    25 ll ddfs(int now,int fa)
    26 {
    27     ll ans=0;
    28     for(int i=head[now];i!=-1;i=edge[i].nxt)
    29     {
    30         int to=edge[i].to;
    31         if(to==fa)continue;
    32         ans+=ddfs(to,now)+edge[i].val*abs((ll)n-2*cou[to]);
    33     }
    34     return ans;
    35 }
    36 int main()
    37 {
    38     memset(head,-1,sizeof(head));
    39     scanf("%d",&n);
    40     for(int i=1;i<n;i++)
    41     {
    42         scanf("%d%d%d",&u,&v,&w);
    43         add(u,v,w),add(v,u,w);
    44         cou[i]=1;
    45     }cou[n]=1;
    46     dfs(1,-1);
    47     printf("%lld",ddfs(1,-1));
    48     return 0;
    49 }
  • 相关阅读:
    Codeforces 834D The Bakery
    hdu 1394 Minimum Inversion Number
    Codeforces 837E Vasya's Function
    Codeforces 837D Round Subset
    Codeforces 825E Minimal Labels
    Codeforces 437D The Child and Zoo
    Codeforces 822D My pretty girl Noora
    Codeforces 799D Field expansion
    Codeforces 438D The Child and Sequence
    Codeforces Round #427 (Div. 2) Problem D Palindromic characteristics (Codeforces 835D)
  • 原文地址:https://www.cnblogs.com/Qin-Wei-Kai/p/10161481.html
Copyright © 2011-2022 走看看