题目链接:http://codeforces.com/contest/743/problem/D
好长时间没写树DP了,从打完比赛那天就一直想怎么写,感觉很生疏。写第二个DFS时卡了,请教了老房,学了一发他的UMAX,很巧妙。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int maxn = 2e5+5; typedef long long ll; ll arr[maxn]; ll sum[maxn]; ll son[maxn]; int vis[maxn]; vector<int> g[maxn]; const ll inf = 0x3f3f3f3f3f3f3f3f; ll dfs1(int u) { int tt = g[u].size(); int flag = 0; sum[u] += arr[u]; for(int i=0;i<tt;i++) { int v = g[u][i]; if(vis[v]) continue; vis[v] = 1; ll tmp = dfs1(v); sum[u] += tmp; flag = 1; son[u] = max(son[u],son[v]); } if(!flag) sum[u] = arr[u]; son[u] = max(son[u],sum[u]); return sum[u]; } ll ans = -inf; void UMAX(ll& a,ll& b,ll c) { if(c>a) { b = a; a = c; } else { if(c>b) { b = c; } } } void dfs2(int u) { ll a = -inf; ll b = -inf; int tt = g[u].size(); for(int i=0;i<tt;i++) { int v = g[u][i]; if(vis[v]) continue; vis[v] = 1; dfs2(v); UMAX(a,b,son[v]); } if(b!=-inf) ans = max(ans,a+b); } int main() { int n;cin>>n; for(int i=1;i<=n;i++) { scanf("%I64d",&arr[i]); } for(int i=1;i<=n-1;i++) { int u,v; scanf("%d %d",&u,&v); g[u].push_back(v); g[v].push_back(u); } memset(son,-inf,sizeof(son)); memset(sum,0,sizeof(sum)); memset(vis,0,sizeof(vis)); vis[1] = 1; dfs1(1); memset(vis,0,sizeof(vis)); vis[1] = 1; dfs2(1); if(ans==-inf) { printf("Impossible "); } else { printf("%I64d ",ans); } return 0; }
论姿势巧妙,还属陈老师
#include<cstdio> #include<algorithm> typedef long long ll; const int N=200010; const ll inf=1LL<<60; int n,i,x,y,a[N],g[N],v[N<<1],nxt[N<<1],ed;ll f[N],dp[N],ans=-inf; inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;} void dfs(int x,int y){ f[x]=a[x]; dp[x]=-inf; for(int i=g[x];i;i=nxt[i]){ int u=v[i]; if(u==y)continue; dfs(u,x); f[x]+=f[u]; if(dp[x]>-inf)ans=std::max(ans,dp[x]+dp[u]); dp[x]=std::max(dp[x],dp[u]); } dp[x]=std::max(dp[x],f[x]); } int main(){ scanf("%d",&n); for(i=1;i<=n;i++)scanf("%d",&a[i]); for(i=1;i<n;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x); dfs(1,0); if(ans>-inf)printf("%I64d",ans);else puts("Impossible"); }