我的方法还是很笨的吧,虽然想到是树形dp但是一直推不出来,原因应该是没有认真分析出他要怎么转移过来。下次要清醒的模拟一下应该不难。
3728 联合权值
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
题目描述 Description
输入描述 Input Description
输出描述 Output Description
样例输入 Sample Input
样例输出 Sample Output
-----------------------------------------------------------------------------------
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
const int nmax=200001;
vector<int>f[nmax];
ll w[nmax];
ll read(){
ll x=0;
char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)){
x=x*10+c-‘0‘;
c=getchar();
}
return x;
}
int main(){
int n=read();
for(int i=1;i<n;i++){
int u=read(),v=read();
f[u].push_back(v);
f[v].push_back(u);
}
for(int i=1;i<=n;i++){
w[i]=read();
}
ll ans1=-1;
for(int i=1;i<=n;i++){
ll Max=0;
for(int j=0;j<f[i].size();j++){
ans1=max(ans1,w[f[i][j]]*Max);
Max=max(w[f[i][j]],Max);
}
}
ll ans=0;
for(int i=1;i<=n;i++){
ll tmp=0;
for(int j=0;j<f[i].size()-1;j++){
tmp+=w[f[i][j]];
ans+=tmp*w[f[i][j+1]];
}
}
printf("%lld %lld\n",ans1,ans*2%10007);
return 0;
}
-----------------------------------------------------------------------------------
下面是师兄的做法:
-----------------------------------------------------------------------------------
void dfs(int x, int fa = -1) {
mx[x] = cnt[x] = 0;
for(edge* e = head[x]; e; e = e->next) if(e->to != fa) {
dfs(e->to, x);
ans = max(ans, w[x] * mx[e->to]);
ans = max(ans, w[e->to] * mx[x]);
tot = (tot + w[x] * cnt[e->to] + w[e->to] * cnt[x]) % MOD;
(cnt[x] += w[e->to]) %= MOD;
mx[x] = max(mx[x], w[e->to]);
}
}
-----------------------------------------------------------------------------------