算法课程笔记——路径相关树形DP




#include<bits/stdc++.h>usingnamespacestd;
 usingLL = longlong;
 constintN = 2005;
 vector<int>e[N],t;
 structasdf{vector<int> vec;
     LL val;
 };
 vector<asdf>w[N];
 LL dp[N];
 intn,m,k,dep[N]={1},f[N];
 voiddfs(intu){
     for(autov:e[u])
     {
         dfs(v);
         dp[u]+=dp[v];
     }
     for(autot:w[u])
     {
         LL sum=dp[u];
         for(autonw:t.vec)
         {
             sum-=dp[nw];
             for(autov:e[nw]) sum+=dp[v];
         }
         dp[u]=max(dp[u],sum+t.val);
     }
 }
 intmain(){
     cin.tie(0);
     cout.tie(0);
     ios::sync_with_stdio(0);
     cin>>n>>m;
     for(inti=2;i<=n;++i)
     {
         cin>>f[i];
         e[f[i]].push_back(i);
         dep[i]=dep[f[i]]+1;
     }
     for(inti=1,x,y;i<=m;++i)
     {
         LL val;
         cin>>x>>y>>val;
         t.clear();
         while(x!=y)
             if(dep[x]>dep[y]) t.push_back(x),x=f[x];
             elset.push_back(y),y=f[y];
         t.push_back(x);
         w[x].push_back({t,val});
     }
     dfs(1);
     cout<<dp[1];
     return0;
 }


#include<bits/stdc++.h>usingnamespacestd;
 usingLL=longlong;
 intn,m;
 constintN=2005;
 structasdf{intx;
     LL val;
 };
 vector<asdf> w[N];
 vector<int>e[N];
 intdep[N];
 LL dp[N][N];
 voiddfs(intu){
     LL sum=0;
     for(inti=1;i<=dep[u];++i) dp[u][i]=1e18;
     for(autov:e[u])
     {
         dfs(v);
         sum+=dp[v][dep[u]+1];
         if(sum>=1e18)
         {
             cout<<-1;
             exit(0);
         }
         for(inti=1;i<=dep[u];++i)
             dp[u][i]=min(dp[u][i],dp[v][i]-dp[v][dep[u]+1]);
     }
     for(inti=1;i<=dep[u];++i) dp[u][i]+=sum;
     for(autov:w[u])
         dp[u][dep[v.x]]=min(dp[u][dep[v.x]],sum+v.val);
     for(inti=2;i<=dep[u];++i) dp[u][i]=min(dp[u][i],dp[u][i-1]);
 }
 intmain(){
     cin>>n>>m;
     dep[1]=1;
     for(inti=2;i<=n;++i)
     {
         intf;
         cin>>f;
         e[f].push_back(i);
         dep[i]=dep[f]+1;
     }
     for(inti=1;i<=m;++i)
     {
         intx,y;
         LL val;
         cin>>x>>y>>val;
         if(dep[x]>dep[y]) swap(x,y);
         w[y].push_back({x,val});
     }
     dfs(1);
     cout<<dp[1][1];
     return0;
 }



















