zoukankan      html  css  js  c++  java
  • BZOJ2435:[NOI2011]道路修建 (差分)

    Description

    在 W 星球上有 n 个国家。为了各自国家的经济发展,他们决定在各个国家
    之间建设双向道路使得国家之间连通。但是每个国家的国王都很吝啬,他们只愿
    意修建恰好 n – 1条双向道路。 每条道路的修建都要付出一定的费用, 这个费用等于道路长度乘以道路两端的国家个数之差的绝对值。例如,在下图中,虚线所示道路两端分别有 2 个、4个国家,如果该道路长度为 1,则费用为1×|2 – 4|=2。图中圆圈里的数字表示国家的编号。


    由于国家的数量十分庞大,道路的建造方案有很多种,同时每种方案的修建
    费用难以用人工计算,国王们决定找人设计一个软件,对于给定的建造方案,计
    算出所需要的费用。请你帮助国王们设计一个这样的软件。

    Input

    输入的第一行包含一个整数n,表示 W 星球上的国家的数量,国家从 1到n
    编号。接下来 n – 1行描述道路建设情况,其中第 i 行包含三个整数ai、bi和ci,表
    示第i 条双向道路修建在 ai与bi两个国家之间,长度为ci。


    Output

    输出一个整数,表示修建所有道路所需要的总费用。

    Sample Input

    6
    1 2 1
    1 3 1
    1 4 2
    6 3 1
    5 2 1

    Sample Output

    20

    HINT

    n = 1,000,000 1≤ai, bi≤n

    0 ≤ci≤ 10^6

    Solution

    前缀和一下,然后枚举边计算答案即可。

    哦对了这个题容易爆栈……Dfs的时候我少开了long long然后就过了(一开始所有都是long long)

    Code

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #define MAX (1000000+10)
     6 using namespace std;
     7 
     8 struct node{int next,to,len;}edge[MAX*2];
     9 int Father[MAX],Sum[MAX];
    10 int head[MAX],num_edge,n;
    11 long long ans;
    12 
    13 void add(int u,int v,int l)
    14 {
    15     edge[++num_edge].to=v;
    16     edge[num_edge].next=head[u];
    17     edge[num_edge].len=l;
    18     head[u]=num_edge;
    19 }
    20 
    21 void Build(int x)
    22 {
    23     Sum[x]=1;
    24     for (int i=head[x];i;i=edge[i].next)
    25         if (edge[i].to!=Father[x])
    26         {
    27             Father[edge[i].to]=x;
    28             Build(edge[i].to);
    29             Sum[x]+=Sum[edge[i].to];
    30         }
    31 }
    32 
    33 void Dfs(int x)
    34 {
    35     for (int i=head[x];i;i=edge[i].next)
    36         if (edge[i].to!=Father[x])
    37         {
    38             ans+=(long long)edge[i].len*abs(n-(Sum[edge[i].to]<<1));
    39             Dfs(edge[i].to);
    40         }
    41 }
    42 
    43 int main()
    44 {
    45     int u,v,l;
    46     scanf("%d",&n);
    47     for (int i=1;i<=n-1;++i)
    48     {
    49         scanf("%d%d%d",&u,&v,&l);
    50         add(u,v,l); add(v,u,l);
    51     }
    52     Build(1);
    53     Dfs(1);
    54     printf("%lld",ans);
    55 }
  • 相关阅读:
    VS2010中添加MVC3和MVC4
    C#--对象转成XML的方法
    Web优化的措施
    Socket的使用(简单测试)
    WCF、WebAPI、WCFREST、WebService之间的区别
    Java和C#(笔记)
    各种窗口最小化快捷键详解
    SASS的安装及使用(前提:安装Ruby)
    查看Linux是32位还是64位
    log4j输出日志到文件
  • 原文地址:https://www.cnblogs.com/refun/p/8678606.html
Copyright © 2011-2022 走看看