NC204272. 旗鼓相当的对手
描述
输入描述
第一行两个整数,意义和题面给定的一致.第二行个整数表示战力值.接下来行每行两个数表示之间有一条边.
输出描述
一行输出个整数表示每个炉石玩家的.按照标号顺序输出.
示例1
输入:
3 2 1 2 3 1 2 1 3
输出:
5 0 0
C++14(g++5.4) 解法, 执行用时: 211ms, 内存消耗: 30436K, 提交时间: 2020-04-02 22:16:22
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 2e5 + 10; #define fi first #define se second #define pb push_back int n,f,a[N]; vector<int>v[N]; map<int,LL>s[N]; map<int,LL>sz[N]; LL ans[N]; void dfs(int x,int y){ LL tot=0; for(auto k:v[x]){ if(k==y) continue; dfs(k,x); for(auto g:s[k]){ if(g.fi+1<f && sz[x][f-g.fi-1]){ tot+=g.se*sz[x][f-g.fi-1]+s[x][f-g.fi-1]*sz[k][g.fi]; } } for(auto g:s[k]){ s[x][g.fi+1]+=g.se; } for(auto g:sz[k]){ sz[x][g.fi+1]+=g.se; } sz[k].clear(); s[k].clear(); } s[x][0]+=a[x]; sz[x][0]++; ans[x]=tot; } int main() { ios::sync_with_stdio(false); cin>>n>>f; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<n;i++){ int s,t; cin>>s>>t; v[s].pb(t); v[t].pb(s); } dfs(1,0); for(int i=1;i<=n;i++)cout<<ans[i]<<' '; return 0; }