列表

详情


NC54584. 小琛和他的学校

描述

小琛是一所学校的校长。 
他的学校有n个校区(编号1~n),被n-1条双向道路连接,呈树形结构。
第i个校区共有Ai个学生。
第i天早上,所有的学生会沿最短路走到第i个校区参加活动,晚上再原路返回。
一个人通过第j条通道一次(即一人次),需要小琛支付wj的维护费用。
小琛想知道第n天结束之后,对于每一条通道,他总共需要支付多少费用。
对于100%的数据,1≤ n  200,000,1 A[i] 10,000,1 w[i] 10,000。

输入描述

第一行一个整数n,表示校区的数量。
接下来一行,n个整数,表示A1~An
第3到第n+1行,每行包含3个整数。第i行包含三个整数ui-2,vi-2,wi-2,表示第i-2条通道所连接的两个校区的编号,以及一人次通过这条通道的费用。

输出描述

共n-1行,每行一个整数。
第i行的整数表示小琛对于第i条通道所需支付的费用。

示例1

输入:

4
2 1 2 3
1 3 1
1 2 3
4 1 2

输出:

24
60
56

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 261ms, 内存消耗: 22240K, 提交时间: 2019-12-27 19:15:52

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+5;
struct P {
	int v,w,id;
};
vector<P> G[N];
int a[N],num[N],n;
ll S,sum[N],ans[N];
void dfs(int u,int fa) {
	sum[u]=a[u],num[u]=1;
	for(int i=0;i<G[u].size();i++) {
		int v=G[u][i].v,w=G[u][i].w,id=G[u][i].id;
		if(v==fa) continue;
		dfs(v,u);
		sum[u]+=sum[v];
		num[u]+=num[v];
		ans[id]=(sum[v]*(n-num[v])+(S-sum[v])*num[v])*w;
	}
}
int main() {
	scanf("%d",&n);
	for(int i=1;i<=n;i++) {
		scanf("%d",&a[i]);
		S+=a[i];
	}
	for(int i=1,u,v,w;i<n;i++) {
		scanf("%d%d%d",&u,&v,&w);
		G[u].push_back({v,w,i});
		G[v].push_back({u,w,i});
	}
	dfs(1,-1);
	for(int i=1;i<n;i++) {
		printf("%lld\n",ans[i]*2);
	}
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 664ms, 内存消耗: 22928K, 提交时间: 2020-01-02 20:56:47

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int n=2e5+5;
struct node
{
	int v,w,id;
};
vector<node>G[n];
int a[n],s,r[n],h[n],t;
ll ans[n];
void dfs(int u,int aft)
{
	r[u]=a[u];h[u]=1;
	for(int i=0;i<G[u].size();i++)
	{
	   int v=G[u][i].v;int id=G[u][i].id;int w=G[u][i].w;
		 if(v==aft) continue;
		 dfs(v,u);
		 r[u]+=r[v];
		 h[u]+=h[v];
		 ans[id]=((1ll*((s-r[v])*h[v]))+(1ll*(t-h[v])*r[v]))*w*2;
	}
}
int main()
{
	cin>>t;
	for(int i=1;i<=t;i++){cin>>a[i];s+=a[i];}
	for(int i=1;i<t;i++)
	{
		int u,v,w;
		cin>>u>>v>>w;
		G[u].push_back({v,w,i});
		G[v].push_back({u,w,i});
	}
	dfs(1,-1);
	for(int i=1;i<t;i++)
	cout<<ans[i]<<'\n';
}

上一题