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\n",dp[1][k]);
    return 0;
}

先码住

猜你喜欢

转载自www.cnblogs.com/shiliuxinya/p/12037802.html