Barn (2012 acm-icpc 长春邀请赛 K题 )树型dp
比赛时调试了半天没A掉,妹子的!!!又打铁了,现在补一下,不知是否正确
#include<iostream> #include<cstring> #include <cstdio> #include<string> #include<queue> #include<vector> #include<map> #include <set> #include<ctime> #include<cmath> #include <cstdlib> #include<algorithm> using namespace std; #define LL long long const LL N=10000+10; const LL INF=INT_MAX; vector< pair<LL,LL> > G[N]; bool vis[N]; LL c[N],x[N],low[N],sum[N]; LL rsum[N],up[N]; LL root=0; void dfs1(LL u){ vis[u]=1; for(LL i=0;i<G[u].size();i++){ LL v=G[u][i].first,w=G[u][i].second; if(!vis[v]){ dfs1(v); low[u]+=low[v]; sum[u]+=sum[v]+low[v]*w; } } low[u]+=x[u]; } void dfs2(LL u){ vis[u]=1; for(LL i=0;i<G[u].size();i++){ LL v=G[u][i].first,w=G[u][i].second; if(!vis[v]){ up[v]=low[root]-low[v]; rsum[v]=rsum[u]+sum[u]-sum[v]-low[v]*w+up[v]*w; dfs2(v); } } } int main(){ LL n; while(scanf("%lld",&n)!=EOF){ for(LL i=0;i<n;i++){ G[i].clear(); } LL sum_num=0; for(int i=0;i<n;i++) { scanf("%lld",&x[i]); sum_num+=x[i]; } for(int i=0;i<n;i++) scanf("%lld",&c[i]); for(LL i=0;i<n-1;i++){ LL u,v,w; scanf("%lld%lld%lld",&u,&v,&w); G[v].push_back(make_pair(u,w)); G[u].push_back(make_pair(v,w)); } //cout<<endl; //for(LL i=0;i<n;i++){ // cout<<i<<" : "; // for(LL j=0;j<G[i].size();j++){ // cout<<G[i][j].first<<" "<<G[i][j].second<<" | "; // } // cout<<endl; //} memset(vis,0,sizeof(vis)); dfs1(root); //cout<<endl; //for(LL i=0;i<n;i++){ // cout<<sum[i]<<endl; //} memset(vis,0,sizeof(vis)); dfs2(root); //cout<<endl; //for(LL i=0;i<n;i++){ // cout<<sum[i]<<" "<<rsum[i]<<" "<<low[i]<<" "<<up[i]<<endl; //} LL ans_id=0,ans_sum=INF; for(LL i=0;i<n;i++){ LL a=rsum[i]+sum[i]+sum_num*c[i]; if(ans_sum>a){ ans_id=i; ans_sum=a; } } printf("%lld %lld\n",ans_id,ans_sum); } }