标签:dig add ++ 思路 color mat hid string mes
题目大意:
一棵树,给定根节点,可以给某些边加上一些权值,每加一,答案加一
求最小答案使根节点到每个叶子节点路径上的权值和相
思路:
树形dp
对于每个节点,dp表示到该节点的所有叶子节点 满足题目的最小答案
转移可以根据它所有子节点转移
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #include<cstdlib> 7 #include<set> 8 #include<map> 9 #include<vector> 10 #include<stack> 11 #include<queue> 12 #define ll long long 13 #define inf 2147383611 14 #define MAXN 500100 15 using namespace std; 16 inline ll read() 17 { 18 ll x=0,f=1; 19 char ch;ch=getchar(); 20 while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();} 21 while(isdigit(ch)) {x=x*10+ch-‘0‘;ch=getchar();} 22 return x*f; 23 } 24 int n,rt,fa[MAXN]; 25 int next[MAXN*2],to[MAXN*2],first[MAXN],val[2*MAXN],cnt; 26 ll ans,dp[MAXN]; 27 void add(int u,int v,int d) {next[++cnt]=first[u],first[u]=cnt,to[cnt]=v,val[cnt]=d;} 28 void dfs(int x,int fa) 29 { 30 for(int i=first[x];i;i=next[i]) 31 { 32 if(to[i]==fa) continue; 33 dfs(to[i],x); 34 dp[x]=max(dp[x],dp[to[i]]+val[i]); 35 } 36 for(int i=first[x];i;i=next[i]) if(to[i]!=fa) ans+=dp[x]-dp[to[i]]-val[i]; 37 } 38 int main() 39 { 40 n=read(),rt=read(); 41 int a,b,c; 42 for(int i=1;i<n;i++) {a=read(),b=read(),c=read();add(a,b,c);add(b,a,c);} 43 dfs(rt,0); 44 printf("%lld",ans); 45 }
标签:dig add ++ 思路 color mat hid string mes
原文地址:http://www.cnblogs.com/yyc-jack-0920/p/7725797.html