• ccf 201909-5


    #include <bits/stdc++.h>
    
    using namespace std;
    
    //dp[u][p]表示以u为根节点的树,选取了p个重要结点的距离之和的最小值 
    
    const int maxn = 5e4+100;
    int head[maxn];    //存以i为起点的最近加入的一条边的存储位置 
    int tot;        //边的编号 
    
    int dp[maxn][102];    //dp[u][p]:以u为根节点选取p个重要节点的最小权值 
    int k;
    bool good[maxn];    //是否是重要节点 
    int num[maxn];        //以u为根节点的树中重要节点的个数 
    int tree_u_v[102];    //临时变量区 
    
    struct Node{        //链式前向星 struct
        int to;        //边的终点     
        int w;        //权值 
        int next;    //相同起点的上一次加入的边的存储位置 
    }edge[maxn*2];
    
    void init(){
        tot = 0;
        memset(head,-1,sizeof(head));    //将head初始化为-1 
    }
    
    void add_edge(int from, int to, int w){        //from起点, to终点, w权值 
        edge[tot].to=to;
        edge[tot].w=w;
        edge[tot].next=head[from]; //head[from]:上一次加入的边的位置 
        head[from]=tot++;          //更新以from为起点的最新加入的边的编号 
    }
    
    void dfs(int u, int fa){    //u节点,fa:u的父亲 
        dp[u][0]=0;            //选取0个重要节点,权值为0 
        if(good[u]){        //如果u本身是重要节点 
            dp[u][1]=0;        //选自己,但是有一个节点,所以权值还是0 
            num[u]=1;
        }
        for(int i=head[u]; i!=-1; i=edge[i].next){        //遍历u的邻接点 
            if(edge[i].to == fa)    continue;
            int v = edge[i].to;
            int w = edge[i].w;
            dfs(v,u);                //dfs u的子节点 
            for(int j=0;j<=k;j++)    tree_u_v[j] = dp[u][j];        //保留更新前的数据 
            int nU = min(k,num[u]);            //最多不能超过k 
            int nV = min(k,num[v]);
            num[u]+=num[v];
            for(int j=0;j<=nU;++j){            //不明白 ! 
                for(int t=0; t<=nV && t+j<=k; ++t)        //j、t、状态转移方程 不理解 
                    dp[u][j+t] = min(1ll*dp[u][j+t], 1ll*(k-t)*t*w + tree_u_v[j] + dp[v][t]);
            }                     //要乘 1ll 否则会溢出 
        }
    }
    
    int main(){
        int n,m,x,y,d;
        scanf("%d %d %d",&n,&m,&k);
        for(int i=0;i<m;i++){
            scanf("%d",&x);
            good[x]=true;
        }
        init();
        for(int i=1;i<n;i++){
            scanf("%d %d %d",&x,&y,&d);
            add_edge(x,y,d);
            add_edge(y,x,d);
        }
        memset(dp,0x3f,sizeof(dp));
        dfs(1,-1);
        printf("%d
    ",dp[1][k]);
        return 0;
    }

    先码住

  • 相关阅读:
    hiveserver2 with kerberos authentication
    python Basic usage
    python Quicksort demo
    Python HeapSort
    mrunit for wordcount demo
    CCDH证书
    Hadoop question list
    Hadoop Yarn core concepts
    Hadoop Resource
    Hadoop could not find or load main class
  • 原文地址:https://www.cnblogs.com/shiliuxinya/p/12037802.html
Copyright © 2020-2023  润新知