• bzoj 2435 dfs处理


    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

    题意:Σ(边的权值*abs(左边点的个数-右边点的个数))
     
    题解:dfs处理 邻接表或vector存图
      n个点n-1条边 找个任意点为根,dfs 得到以该点为子树的树的大小k 
      Σ(边的权值*abs(k-(n-k)))
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #define ll long long
     6 using namespace std;
     7 struct node
     8 {
     9     int pre;
    10     int to;
    11     int w;
    12 }N[2000040];
    13 int nedge=0;
    14 int pre[1000020];
    15 int n;
    16 int used[1000020];
    17 int s[1000020];
    18 ll ans=0;
    19 void add(int a,int b,int c)
    20 {
    21     nedge++;
    22     N[nedge].to=b;
    23     N[nedge].w=c;
    24     N[nedge].pre=pre[a];
    25     pre[a]=nedge;
    26 }
    27 int  ab(int x)
    28 {
    29     if(x<0)
    30         return -x;
    31     return x;
    32 }
    33 void dfs(int xx)
    34 {
    35     s[xx]=1;
    36     for(int i=pre[xx];i;i=N[i].pre)
    37     {
    38         if(!used[N[i].to])
    39         {
    40             used[N[i].to]=1;
    41             dfs(N[i].to);
    42             s[xx]+=s[N[i].to];
    43             ans=ans+(ll)N[i].w*ab(s[N[i].to]-(n-s[N[i].to]));
    44         //cout<<"!!!"<<N[i].w<<" "<<s[xx]<<" "<<n-s[xx]<<endl;
    45         }
    46     }
    47 }
    48 int aa,bb,cc;
    49 int main()
    50 {
    51     while(scanf("%d",&n)!=EOF)
    52    {
    53     memset(used,0,sizeof(used));
    54     nedge=0;
    55     ans=0;
    56     memset(pre,0,sizeof(pre));
    57     memset(s,0,sizeof(s));
    58     for(int i=1;i<n;i++)
    59     {
    60       scanf("%d %d %d",&aa,&bb,&cc);
    61       add(aa,bb,cc);
    62       add(bb,aa,cc);
    63     }
    64     used[1]=1;
    65     dfs(1);
    66     printf("%lld
    ",ans);
    67    }
    68     return 0;
    69 }
     
  • 相关阅读:
    多种支付实现(只需要添加, 修改类方法)
    事务的隔离级别 另一种事务开启方式
    序列化类补充 source关键字参数 SerializerMethodField方法
    分类的数据处理 第一种递归处理,第二种树型结构 无极限分类
    数据库补充 navicate导入与导出
    微信小程序开发5 后端解析wx.getUserInfor中的用户信息, 微信小程序支付
    微信小程序开发4 登录与授权
    微信小程序开发3 自定义组件(传参), 页面跳转(传参), 小程序本地存储, 小程序向django请求接口
    前八后十六节奏
    [编织消息框架][JAVA核心技术]动态代理应用11-水平扩展实现
  • 原文地址:https://www.cnblogs.com/hsd-/p/5664091.html
Copyright © 2020-2023  润新知