题意:给你一棵树,让你求一点,使该点到其余各点的距离之和最小。如果这样的点有多个,则按升序依次输出。

树型dp

#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
using namespace std;
const int maxn=50010;
typedef __int64 LL;
vector<int>tree[maxn];// to save the relation
LL f[maxn],g[maxn],dp[maxn];//f[u] u as root to all his sons' distance g[u]the number of u'sons
set<int> myqueue;
void dfs(int u,int pa){
/* 以1为根,所有的子树到他们的子节点的和 */
    if(tree[u].size() == 1 && u != 1){
        g[u]=1;
        f[u]=0;
        return;
    }
    for(int v=0;v < tree[u].size();v++){
        if(tree[u][v]!=pa){
            dfs(tree[u][v],u);
            g[u]+=g[tree[u][v]];//the son's sons' number
            f[u]+=f[tree[u][v]]+g[tree[u][v]];
        }
    }
    g[u]++;// himself
}
void dfs2(int u,int pa){// to sum the way from his father
//再考虑从父节点来的
    if(tree[u].size()==1 && u!=1){
        dp[u]=dp[pa]+g[1]-(g[u]<<1);
        return;
    }
    for(int v=0;v<tree[u].size();v++){
        if(tree[u][v]!= pa){
//到某节点的距离的和=该节点子树的距离和(在dfs1中获得)+从父亲那一支子树获得的和(此时,父节点那一支看成子树)。dp[儿子]=dp[父节点]-dp[儿子]-g[儿子](儿子到父节点这条路被减了子树的子节点数的次数)    + dp[儿子]+(g[1]-g[儿子])(父树上的所有节点)
            dp[tree[u][v]]=dp[u]+g[1]-(g[tree[u][v]]<<1);
            dfs2(tree[u][v],u);//先算了之后再跑子树
        }
    }
}
int main(){
    int t;
    int n,I,R,a,b;
    scanf("%d",&t);
    LL mmin;
    while(t--){
        scanf("%d%d%d",&n,&I,&R);

        for(int i=0;i<=n;i++){
            tree[i].clear();
        }
        for(int i=2;i<=n;i++){
            scanf("%d%d",&a,&b);
            tree[a].push_back(b);
            tree[b].push_back(a);
        }
//        for(int i=0;i<=n;i++){
//            for(int j=0;j<tree[i].size();j++){
//                printf("%d ",tree[i][j]);
//            }
//            printf("\n");
//        }
        memset(f,0,sizeof(f));
        memset(g,0,sizeof(g));
        dfs(1,-1);
        dp[1]=f[1];
        dfs2(1,-1);
        mmin=dp[1];
        myqueue.clear();
        myqueue.insert(1);
        for(int i=2;i<=n;i++){
            if(dp[i]<mmin){
                mmin=dp[i];
                myqueue.clear();
                myqueue.insert(i);
            }
            if(dp[i]==mmin) myqueue.insert(i);
        }
        //warning : output long long should be I64d
        printf("%I64d\n",I*I*R*mmin);//use set not num but the op
            for(set<int>::iterator it=myqueue.begin();it!=myqueue.end();++it){
                printf("%d ",*it);
            }
        printf("\n\n");
    }
}

  

Power Station POJ 4045的更多相关文章

  1. Power Network (poj 1459 网络流)

    Language: Default Power Network Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 23407   ...

  2. Power Network - poj 1459 (最大流 Edmonds-Karp算法)

      Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 24788   Accepted: 12922 Description A ...

  3. Building a Space Station POJ - 2031

    Building a Space Station POJ - 2031 You are a member of the space station engineering team, and are ...

  4. Power Strings POJ - 2406

    Power Strings POJ - 2406 时限: 3000MS   内存: 65536KB   64位IO格式: %I64d & %I64u 提交 状态 已开启划词翻译 问题描述 Gi ...

  5. poj - 4045 - Power Station

    题意:一棵有n个结点的树,要取其中的一个结点,使得该结点到其他所有结点的距离和dis最小,即损耗I * I * R * dis最小,输出最小损耗和该结点(有多个的话按结点编号从小到大输出)(3 < ...

  6. ( KMP 求循环节的个数)Power Strings -- poj -- 2406

    链接: http://poj.org/problem?id=2406 Power Strings Time Limit:3000MS     Memory Limit:65536KB     64bi ...

  7. (最小生成树) Building a Space Station -- POJ -- 2031

    链接: http://poj.org/problem?id=2031 Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6011 ...

  8. Building a Space Station POJ 2031 【最小生成树 prim】

    http://poj.org/problem?id=2031 Description You are a member of the space station engineering team, a ...

  9. Power Strings (poj 2406 KMP)

    Language: Default Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 33205   ...

随机推荐

  1. 一种好的持久层开发方法——建立BaseDao和BaseDaoImpl

    使用hibernate开发持久层时,我们会发现:虽然entity类的含义和需求不同,其对应的Dao层类对应的方法也是不同的.但是有许多方法操作确实相同的.比如实体的增加,删除,修改更新,以及许多常用的 ...

  2. Java中浮点数的基础知识

    偶然查看Math.round的JDK public static int round(float a) { if (a != 0x1.fffffep-2f) // greatest float val ...

  3. opencv java api提取图片sift特征

    opencv在2.4.4版本以后添加了对java的最新支持,可以利用java api了.下面就是我利用opencv的java api 提取图片的sift特征. import org.opencv.co ...

  4. 3.12php

    这是我的第一个博客  纪念一下  反正都是自己看 第一个问题 出现错误 当图片超过1M时就可能出现以下错误  当然这个也跟你php.ini设置有关 如果你php设置里 memory_limit 16M ...

  5. MacOS10.9获取Android源码不完全笔记(2014)

    第一步:安装Macports 这个我就不叙述了,网上有无数教程 第二步:创建一个磁盘镜像 1.打开磁盘工具,然后: 第三步:使用Macport安装编译环境 1.打开终端输入以下内容 sudo port ...

  6. stm32之ADC学习

    1.stm32中采用的是逐次逼近型模拟数字方式,那么什么是逐次逼近呢? 逐次逼近的方式类似于二分法,以8位数据为例:当输入一个模拟量的时候,首先取这8位数的一半,即1000 0000,与模拟量比较,大 ...

  7. 使用plspl创建orcale作业

    1.由于权限问题,第一步应先以sys账户登录,路径:工具->DBMS 调试程序->作业  ,新建一个作业,出现如下图的窗口 2.开始依次填写相应内容,Name为作业名字,注意要加上用户名前 ...

  8. NSInvocation的使用(转)

    转载自:http://www.cnblogs.com/pengyingh/articles/2359199.html http://blog.iosxcode4.com/?p=125 在 iOS中可以 ...

  9. (转载)Unity3d摄像机Camera参数详解

    1. Clear Flags:清除标记.决定屏幕的哪部分将被清除.一般用户使用对台摄像机来描绘不同游戏对象的情况,有3中模式选择: Skybox:天空盒.默认模式.在屏幕中的空白部分将显示当前摄像机的 ...

  10. 【BZOJ 1798】 [Ahoi2009]Seq 维护序列seq

    Description 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2 ...