标签:wal mis limit contain names tor content return ane
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=3899
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1375 Accepted Submission(s): 413
题意:
给定N个节点的点权Ti[i],N-1条边的权值,以某点为根的代价是,所有点的点权值*到树根的距离,找出最小的代价。
Hint:
树上递推
假设求得以a为树根的总代价,b是a的子节点,tot是树的总点权值,则以b为树根的代价,与a相比
多了tot-size[b] 少了size[a] 倍的edge(a,b)
递推写法:
#include<bits/stdc++.h> #define Pii pair<int,long long> #define fi first #define se second #define INF 0x7fffffff #define pb push_back #define mp make_pair #define maxn 101000 #define LL long long using namespace std; vector<Pii> G[maxn]; int n,m,Ti[maxn],size[maxn]; LL tot,res=0,ans=0; void dfs(int x,int fa,LL cnt){ Pii now; size[x]=Ti[x]; ans+=cnt*Ti[x]; for(int i=0;i<G[x].size();i++){ now=G[x][i]; if(now.fi==fa) continue; dfs(now.fi,x,cnt+now.se); size[x]+=size[now.fi]; } } void solve(int x,int fa,LL cnt){ ans=min(ans,cnt); Pii now; for(int i=0;i<G[x].size();i++){ now=G[x][i]; if(now.fi==fa) continue; solve(now.fi,x,cnt+now.se*(tot-2*size[now.fi])); } } int main(){ int T; int u,v,w; while(scanf("%d",&n)!=EOF){ tot=0; for(int i=1;i<=n;i++) cin>>Ti[i],tot+=Ti[i]; for(int i=1;i<n;i++){ cin>>u>>v>>w; G[u].pb(mp(v,w)); G[v].pb(mp(u,w)); } ans=0; dfs(1,-1,0); solve(1,-1,ans); cout<<ans<<endl; for(int i=1;i<=n;i++) G[i].clear(); } return 0; }
DP写法:
1 #include<bits/stdc++.h> 2 #define Pii pair<int,long long> 3 #define fi first 4 #define se second 5 #define INF 0x7fffffff 6 #define pb push_back 7 #define mp make_pair 8 #define maxn 101000 9 #define LL long long 10 using namespace std; 11 vector<Pii> G[maxn]; 12 int n,m,Ti[maxn],size[maxn]; 13 LL tot,res=0,ans=0,dp[maxn]; 14 void dfs(int x,int fa,LL cnt){ 15 Pii now; 16 size[x]=Ti[x]; 17 ans+=cnt*Ti[x]; 18 for(int i=0;i<G[x].size();i++){ 19 now=G[x][i]; 20 if(now.fi==fa) continue; 21 dfs(now.fi,x,cnt+now.se); 22 size[x]+=size[now.fi]; 23 } 24 } 25 void solve(int x,int fa){ 26 Pii now; 27 for(int i=0;i<G[x].size();i++){ 28 now=G[x][i]; 29 if(now.fi==fa) continue; 30 dp[now.fi]=dp[x]+now.se*(tot-2*size[now.fi]); 31 solve(now.fi,x); 32 } 33 } 34 int main(){ 35 int T; 36 int u,v,w; 37 while(scanf("%d",&n)!=EOF){ 38 tot=0; 39 for(int i=1;i<=n;i++) cin>>Ti[i],tot+=Ti[i]; 40 for(int i=1;i<n;i++){ 41 cin>>u>>v>>w; 42 G[u].pb(mp(v,w)); 43 G[v].pb(mp(u,w)); 44 } 45 ans=0; 46 dfs(1,-1,0); 47 dp[1]=ans; 48 solve(1,-1); 49 for(int i=1;i<=n;i++) ans=min(ans,dp[i]); 50 cout<<ans<<endl; 51 for(int i=1;i<=n;i++) G[i].clear(),dp[i]=0; 52 } 53 return 0; 54 }
标签:wal mis limit contain names tor content return ane
原文地址:http://www.cnblogs.com/poler/p/7258008.html