题解 | #[NOIP2014]联合权值#

[NOIP2014]联合权值

https://ac.nowcoder.com/acm/problem/16495

#include<bits/stdc++.h>
using namespace std;
const int mo=10007;
#define maxm 200010
#define ll long long
ll w[maxm];
vector<int>G[maxm];
struct node{
    ll v,sum1,sum2;
}f[maxm],ne[maxm];

void dfs(int u,int pr){
	vector<int>S;
	for(int i=0;i<(int)G[u].size();i++){
		int v=G[u][i];
		if(pr==v)continue;
        dfs(v,u);
		S.push_back(v);
        ne[u].sum1=(ne[u].sum1+w[v])%mo;
        ne[u].v=max(ne[u].v,w[v]);
        f[u].v=max(f[u].v,ne[v].v);
        f[u].sum1=(f[u].sum1+ne[v].sum1);
	}
    ll maxv=0;
    int sum=0;
    for(int i=0;i<S.size();i++){
        int v=S[i];
        f[v].sum2=(f[v].sum2+sum)%mo;
        f[v].v=max(f[v].v,maxv);
        sum=(sum+w[v])%mo;
        maxv=max(maxv,w[v]);
    }
    maxv=0;sum=0;
	for(int i=S.size()-1;i>=0;i--){
        int v=S[i];
        f[v].sum2=(f[v].sum2+sum)%mo;
        f[v].v=max(f[v].v,maxv);
        sum=(sum+w[v])%mo;
        maxv=max(maxv,w[v]);
    }
    
	
}
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n-1;i++){
		int x,y;
		cin>>x>>y;
		G[x].push_back(y);
		G[y].push_back(x);
	}
	for(int i=1;i<=n;i++) cin>>w[i];
	dfs(1,0);
    ll maxv=0,sum=0;
	for(int i=1;i<=n;i++){
        maxv=max(maxv,w[i]*f[i].v);
        sum=(sum+f[i].sum1*2*w[i]+w[i]*f[i].sum2)%mo;
    }
    cout<<maxv<<' '<<sum;
	return 0;
}

这道题类似于树形dp

先求出每个点的最大联合权值以及每个点相关的权值对的和,然后max即可

全部评论

相关推荐

不愿透露姓名的神秘牛友
07-07 13:46
点赞 评论 收藏
分享
06-18 13:28
已编辑
门头沟学院 Web前端
爱睡觉的冰箱哥:《给予你300的工资》,阴的没边了
点赞 评论 收藏
分享
门口唉提是地铁杀:之前b站被一个游戏demo深深的吸引了。看up主页发现是个初创公司,而且还在招人,也是一天60。二面的时候要我做一个登录验证和传输文件两个微服务,做完要我推到github仓库,还要我加上jaeger和一堆运维工具做性能测试并且面试的时候投屏演示。我傻乎乎的做完以后人家跟我说一句现在暂时不招人,1分钱没拿到全是白干
你的秋招第一场笔试是哪家
点赞 评论 收藏
分享
码农索隆:有点耳熟,你们是我教过最差的一届
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务