zoukankan      html  css  js  c++  java
  • [BZOJ]3727: PA2014 Final Zadanie

     题解:  我们可以得到   

          $  b[fa_i]+Sum-2*sz[i]=b[i] $

    然后我们把n-1条边的价值求和起来化简

          $  (n-1)*Sum-2*b[1]=sum_{i=2}^{n}b[i]-b[fa_i] $

    然后我们就能求得所有节点的$a[i]$的求和 然后做个树dp带入原始方程即可求得每个位置的$a[i]$

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=3e5+10;
    const double eps=1e-8;
    #define ll long long
    using namespace std;
    struct edge{int t;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
    void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;}
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    
    
    ll b[MAXN],a[MAXN],c[MAXN];
    
    ll sum,Sum;
    
    void dfs(int x,int pre){
        link(x){
    	if(j->t==pre)continue;
    	sum+=b[j->t]-b[x];
    	dfs(j->t,x);
        }
    }
    
    void _dfs(int x,int pre){
        link(x){
    	if(j->t==pre)continue;
    	_dfs(j->t,x);
    	c[x]+=c[j->t];
        }
        if(x!=1)a[x]=(Sum+b[pre]-b[x])/2-c[x],c[x]+=a[x];
    }
    
    int main(){
        int n=read();
        int x,y;
        inc(i,2,n)x=read(),y=read(),add(x,y),add(y,x);
        inc(i,1,n)b[i]=read();
        sum=0;dfs(1,0);
        Sum=(2*b[1]+sum)/(n-1);
        _dfs(1,0);
        a[1]=Sum-c[1];
        inc(i,1,n)printf("%lld ",a[i]);
    }
    

      

    3727: PA2014 Final Zadanie

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 393  Solved: 175
    [Submit][Status][Discuss]

    Description

    吉丽YY了一道神题,题面是这样的:
    “一棵n个点的树,每条边长度为1,第i个结点居住着a[i]个人。假设在i结点举行会议,所有人都从原住址沿着最短路径来到i结点,行走的总路程为b[i]。输出所有b[i]。”
    吉丽已经造好了数据,但熊孩子把输入文件中所有a[i]给删掉了。你能帮他恢复吗?

    Input

    第一行一个整数n(2<=n<=300000)。
    接下来n-1行,每行两个整数x,y,表示x和y之间有连边。
    接下来一行由空格隔开的n个整数b[i](0<=b[i]<=10^9)。

    Output

    输出一行由空格隔开的n个整数a[i]。
    如果你觉得有多组解就任意输出其中一组。

    Sample Input

    2
    1 2
    17 31

    Sample Output

    31 17
  • 相关阅读:
    二分查找思路以及可能出现情况对应解决办法
    多线程知识点大纲
    服务器consul启动方法
    大白话带你认识 ZooKeeper !重要概念一网打尽!
    「Netty实战 02」手把手教你实现自己的第一个 Netty 应用!新手也能搞懂!
    从 BIO、NIO 聊到 Netty,最后还要实现个 RPC 框架!
    什么是P问题、NP问题和NPC问题
    期刊汇总
    Typora 使用
    TCA 复习
  • 原文地址:https://www.cnblogs.com/wang9897/p/10458240.html
Copyright © 2011-2022 走看看