hdu6060-思维&搜索&好题-RXD and dividing

本文介绍了一道关于树结构的算法题目,旨在通过构建特定的子树来最大化斯坦纳树的总费用。通过DFS遍历算法实现,关键在于理解题目要求及优化策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://acm.hdu.edu.cn/showproblem.php?pid=6060
给定一个树,问你把除了1节点之外的节点 分成k份,然后让每一份和1节点 连接成 最小的斯坦纳树(最小生成树是一种特殊的斯坦纳树,所以斯坦纳树就是把所有的节点连通的树。),而图中已经是树了,所以其实就是把他们连接起来(就是题中对应的f函数,但是已经是树了所以不存在最小一说。。连起来只有一种情况啊)。问你最大的花费是多少。
比赛的时候连题意都读错了,因为 k个集合包含了所有的点,所以必然有好多边要重复计算,我们如果想要最大的话,必须让其尽可能多的重复计算。于是就可以构建下图中的情况qwq
这里写图片描述
(图中假定k是3,若大于3,那么中间那两个点应该换成其他颜色,希望更多的和1节点邻接的边的重用 !)
即尽可能的让其子树充满不同的颜色(集合)。取一个 k和siz的 最小值。
一次dfs就可以了。。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e6+12;
struct Node{
     int to;
     int cost;
     Node(){};
     Node(int _a,int _b){to=_a;cost=_b;}
};
vector<Node>G[maxn];
int siz[maxn];
int vc[maxn];
void dfs(int u,int fa){
    //cout<<"!!!!"<<endl;
   siz[u]=1;
    for(int i=0;i<G[u].size();i++){
           int v=G[u][i].to;
           if(v==fa) continue;
           dfs(v,u);
           vc[v]=G[u][i].cost;
           siz[u]+=siz[v];
    }
        //if(!flag) siz[u]=1;
    return ;
}
int main()
{   int m,k;
     int a,b,c;
    while(~scanf("%d%d",&m,&k)){
         for(int i=0;i<maxn;i++)
             G[i].clear();
         for(int i=0;i<m-1;i++){
             scanf("%d%d%d",&a,&b,&c);
             G[a].push_back(Node(b,c));
             G[b].push_back(Node(a,c));
         }
         dfs(1,-1);
         //puts("!!!");
         ll all=0;
         for(int i=2;i<=m;i++){
            all+=1ll*min(siz[i],k)*vc[i];
         }
         printf("%lld\n",all);


    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值