Power Station(2012 acm-icpc 金华邀请赛 B题 )树型dp

最近发现此类题目特别多

#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=60000+10;
const LL INF=INT_MAX;
vector< LL> G[N],ans;
bool vis[N];
LL low[N],c[N],sum[N];
LL root=1;
void dfs1(LL u){
    vis[u]=1;
    for(LL i=0;i<G[u].size();i++){
        LL v=G[u][i];
        if(!vis[v]){
            dfs1(v);
            low[u]+=low[v];
            c[u]+=c[v]+low[v];
        }
    }
    low[u]++;
}
void dfs2(LL u){
    vis[u]=1;
    for(LL i=0;i<G[u].size();i++){
        LL v=G[u][i];
        if(!vis[v]){
            sum[v]=sum[u]-c[v]-low[v]+(low[root]-low[v])+c[v];
            dfs2(v);
        }
    }
}
int main(){
    LL n,I,R,T;
    scanf("%lld",&T);
    while(T--){
        scanf("%lld%lld%lld",&n,&I,&R);
        for(LL i=0;i<=n;i++){
            G[i].clear();
        }
        for(LL i=0;i<n-1;i++){
            LL u,v;
            scanf("%lld%lld",&u,&v);
            G[v].push_back(u);
            G[u].push_back(v);
        }
        //cout<<endl;
        //for(LL i=1;i<=n;i++){
        //    cout<<i<<" : ";
        //    for(LL j=0;j<G[i].size();j++){
        //        cout<<G[i][j]<<" ";
        //    }
        //    cout<<endl;
        //}
        memset(sum,0,sizeof(sum));
        memset(c,0,sizeof(c));
        memset(low,0,sizeof(low));
        memset(vis,0,sizeof(vis));

        dfs1(root);


        memset(vis,0,sizeof(vis));
        sum[root]=c[root];
        dfs2(root);

        //cout<<endl;
        //for(LL i=1;i<=n;i++){
        //    cout<<low[i]<<" "<<c[i]<<" "<<sum[i]<<endl;
        //}
        LL min_num=INF;
        for(LL i=1;i<=n;i++){
            min_num=min(min_num,sum[i]);
        }
        ans.clear();
        cout<<min_num*I*I*R<<endl;
        for(LL i=1;i<=n;i++){
            if(sum[i]==min_num) ans.push_back(i);
        }
        for(LL i=0;i<ans.size();i++){
            if(i!=ans.size()-1) cout<<ans[i]<<" ";
            else cout<<ans[i]<<endl<<endl;
        }
        //cout<<endl;
        //for(LL i=0;i<n;i++){
        //    cout<<sum[i]<<" "<<rsum[i]<<" "<<low[i]<<" "<<up[i]<<endl;
        //}
    }
}
posted @ 2012-05-09 18:26  HaoHua_Lee  阅读(753)  评论(0编辑  收藏  举报