zoukankan      html  css  js  c++  java
  • 计蒜客模拟赛D1T2 蒜头君的树:树上节点之间最短距离和

    题目链接:https://nanti.jisuanke.com/t/16446

    题意:

      给你一棵有n个节点的树以及每条边的长度,输出树上节点之间的最短距离和。然后进行m次操作,每次操作更改一条边的长度,分别输出每次操作后树上节点之间的最短距离和。

    题解:

      最短距离和 = ∑(树上每一条边被最短路经过的次数 * 这条边的长度)

      一个节点到它父节点的边被经过的次数 = 该节点以及它的子孙的节点个数 * 除了该节点和它子孙之外的所有节点总个数

      

      每一个节点以及它子孙节点的个数总和用一遍dfs保存在num数组中,然后算出每个sum[i] = num[i] * (n - num[i]),就可以求出在没有进行任何操作时的最短距离和。

      对于每一次操作将第a个节点到它父节点的边长由原来的len[a]改为b,则将原来的最短距离和dis改为dis + (b - len[a])并输出,同时将len[a]改为b即可。

      预处理&计算操作前的最短距离和的复杂度为O(N),m次询问复杂度O(M),总复杂度为O(N+M)。

      注:本题会爆int,Ctrl+R全换成long long。。。

    AC Code:

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <vector>
    #define MAX_N 100005
    
    using namespace std;
    
    int n,m;
    long long dis=0;
    long long len[MAX_N];
    long long num[MAX_N];
    long long sum[MAX_N];
    vector<int> edge[MAX_N];
    
    void read()
    {
        memset(len,0,sizeof(len));
        cin>>n;
        for(int i=2;i<=n;i++)
        {
            int x,y;
            cin>>x>>y;
            edge[x].push_back(i);
            len[i]=y;
        }
    }
    
    long long dfs(int now)
    {
        long long tot=1;
        for(int i=0;i<edge[now].size();i++)
        {
            tot+=dfs(edge[now][i]);
        }
        num[now]=tot;
        return tot;
    }
    
    void cal_sum()
    {
        for(int i=1;i<=n;i++)
        {
            sum[i]=num[i]*(n-num[i]);
        }
    }
    
    void cal_dis()
    {
        for(int i=1;i<=n;i++)
        {
            dis+=sum[i]*len[i];
        }
    }
    
    void solve()
    {
        dfs(1);
        cal_sum();
        cal_dis();
        cout<<dis<<endl;
        cin>>m;
        for(int i=0;i<m;i++)
        {
            int a,b;
            cin>>a>>b;
            dis+=(b-len[a])*sum[a];
            len[a]=b;
            cout<<dis<<endl;
        }
    }
    
    int main()
    {
        read();
        solve();
    }
  • 相关阅读:
    npm升级package.json依赖包到最新版本号
    vue中 父子组件的通讯
    vue组件开发
    vue模拟后端获取数据——json-server与express
    vue-cli 2.x 搭建项目
    python socket编程
    python异常处理
    python反射
    python特殊成员函数
    Executor ExecutorService Executors
  • 原文地址:https://www.cnblogs.com/Leohh/p/7261131.html
Copyright © 2011-2022 走看看