链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
Crazycth 看见了穿过传送门的你,他邀请你帮助他的室友。
Crazycth 的室友经常深夜看马里奥录播,现在他正梦到自己被库巴追,被迫逃进了一个迷宫。
迷宫可以视为一棵 n 个节点的树,在第 i 个节点有一个大小 wi,颜色为 ci 的蘑菇。
Crazycth 的室友喜欢吃蘑菇,但是相同颜色的蘑菇他只想吃一个,同时每个节点只能经过一次。他可以瞬间算出以任一节点为终点时他所能吃的蘑菇大小总和的最大值。不过他此时忙于在迷宫入口(1 号节点)吃蘑菇,聪明的你能帮忙解决这个问题吗?
输入描述:
第一行包含一个正整数 n(2≤n≤105)n (2\le n \le 10^5)n(2≤n≤105),表示迷宫节点的个数。 第二行包含 nnn 个正整数 w1,w2,…,wnw_1,w_2, \ldots, w_nw1,w2,…,wn (1≤wi≤108)(1 \le w_i \le 10^8)(1≤wi≤108) ,分别表示第 iii 个节点的蘑菇的大小。 第三行包含 nnn 个正整数 c1,c2,…,cn(1≤ci≤n)c_1,c_2, \ldots, c_n (1 \le c_i \le n)c1,c2,…,cn(1≤ci≤n),分别表示第 iii 个节点的蘑菇的颜色。 接下来 n−1n - 1n−1 行,每行两个正整数 ui,vi(1≤ui<vi≤n)u_i,v_i (1 \le u_i \lt v_i \le n)ui,vi(1≤ui<vi≤n),表示连接 uiu_iui 和 viv_ivi 的一条边 。 输入数据保证不存在重边,并且每个节点都可以由起点唯一到达,1 号节点为起点。
输出描述:
输出 n 行,第 i 行包含一个整数,即从 1 号点出发最终到达 i号点时,能吃到的蘑菇的大小总和的最大值。
输入
5
1 4 5 5 9
1 2 2 3 4
1 2
2 3
3 5
1 4
输出
1
5
6
6
15
思路就是dfs深搜,沿途相同颜色的蘑菇要取这一颜色中的最大值。
比赛的时候没回溯好,卡了好久,菜是原罪!
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll c[100001],v[100001],n,vis[100001];
vector<ll> ve[100001];
ll maxx[100001];//记录某种颜色中最大体积
ll sum[100001];
void dfs(ll t,ll s)
{
ll i;
vis[t]=1;
ll huisu=maxx[c[t]];
if(v[t]>maxx[c[t]])//如果该蘑菇在目前相同颜色中最大,减去原本的,加上现在的
{
s-=maxx[c[t]];
maxx[c[t]]=v[t];
s+=v[t];
}
sum[t]=s;
ll pp=ve[t].size();
if(pp>0)
for(i=0;i<pp;i++)
{
ll k=ve[t][i];
if(vis[k]==0)
{
dfs(k,s);
}
}
maxx[c[t]]=huisu;//回溯!!!
vis[t]=0;
}
int main()
{
ll i,a,b;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>v[i];
}
for(i=1;i<=n;i++)
{
cin>>c[i];
}
for(i=0;i<n-1;i++)
{
cin>>a>>b;
ve[a].push_back(b);//建图
ve[b].push_back(a);
}
dfs(1,0);
for(i=1;i<=n;i++)
{
cout<<sum[i]<<'\n';
}
return 0;
}