• 路上路径求和


    A 求和

    时间限制: 1 Sec  空间限制: 256 MB

    输入输出文件名:A.in,A.out

    题目描述

    给出一棵以1为根的有n个节点的树,树上每条边都有其边权。

    求所有点对之间的路径上的边权和的总和。

    输入格式:

    第一行为n

    接下来n-1行,每行三个整数,分别表示一条边的两端点编号和边权。(编号为1..n)

    输出格式:

    输出一个数字表示总和

    输入样例

    4

    1 2 10

    2 3 10

    1 4 20

    输出样例

    130

    样例解释

    1->2:10 , 1->3:20 , 1->4:20 , 2->3:10 , 2->4:30 , 3->4:40 , 总和为130。

    数据范围

    对于30%的数据,1<=n<=300

    对于80%的数据,1<=n<=3000

    对于100%的数据,1<=n<=100000,边权为<=100的正整数。

    —————————————————————————————————————

    这是道套路题QAQ

    单独考虑每条路径就好了

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    using namespace std;
    const int M=1e5+7;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    LL ans,w;
    int vis[M],n,x,y,sz[M];
    int first[M],cnt;
    struct node{int from,to,next;LL w;}e[M*2];
    void ins(int a,int b,LL w){cnt++; e[cnt]=(node){a,b,first[a],w}; first[a]=cnt;}
    void insert(int a,int b,LL w){ins(a,b,w); ins(b,a,w);}
    void dfs(int x){
        vis[x]=1;
        sz[x]=1;
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(!vis[now]){
                dfs(now);
                sz[x]+=sz[now];
            }
        }
    }
    int main()
    {
        n=read();
        for(int i=1;i<n;i++) x=read(),y=read(),w=read(),insert(x,y,w);
        dfs(1);
        for(int i=1;i<=cnt;i+=2){
            int x=sz[e[i].from]<sz[e[i].to]?e[i].from:e[i].to;
            ans=ans+(LL)sz[x]*(n-sz[x])*e[i].w;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    没有精神分裂的测试不是一个好家长
    防火墙中配置开放 8080端口--续上一篇
    rocketMQ(一)基础环境
    如何做一个对账系统
    通用对账系统介绍与设计(上)
    pdf转图片
    虚拟机加载类机制
    jenkins
    zookeeper和dubbo
    正则日常积累
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7343811.html
Copyright © 2020-2023  润新知