acm.hdu.edu.cn/showproblem.php?pid=6060

【题意】

  • 给定一棵以1为根的树,把这颗树除1以外的结点划分为k个集合(可以有空集),把1加入划分后的集合
  • 每个集合的结点形成一棵最小生成树
  • 所有最小生成树的权值之和最大化

【思路】

  • 最小生成树,每个点u到root 1都要有唯一的一条路径,那么显然,u到1沿路的每条边贡献都为1
  • 现在考虑每条边的贡献
  • 对于某条边uv,v是离根更远的结点,以v为根的子树大小为sz[v],显然我们可以通过把sz[v]个结点划分到sz[v]个不同的集合中,使得uv的贡献为sz[v]
  • 当然,sz[v]大于k时我们只能取k

【Accepted】

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
using namespace std;
typedef long long ll;
int n,k;
const int maxn=2e6+;
struct node
{
int v;
ll c;
node(int _v,ll _c):v(_v),c(_c){}
};
vector<node> vec[maxn];
ll ans;
int sz[maxn];
int DFS(int u,int pa)
{
sz[u]=;
for(int i=;i<vec[u].size();i++)
{
int v=vec[u][i].v;
if(v==pa) continue;
sz[u]+=DFS(v,u);
ll cnt=min(sz[v],k);
ans+=vec[u][i].c*cnt;
}
return sz[u];
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF)
{
for(int i=;i<maxn;i++)
{
vec[i].clear();
}
memset(sz,,sizeof(sz));
for(int i=;i<n-;i++)
{
int u,v;
ll c;
scanf("%d%d%lld",&u,&v,&c);
vec[u].push_back(node(v,c));
vec[v].push_back(node(u,c));
}
ans=0ll;
DFS(,-);
printf("%lld\n",ans);
}
return ;
}

vector注意多组数据要清空

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
using namespace std;
typedef long long ll;
int n,k;
const int maxn=2e6+;
struct edge
{
int to;
int nxt;
ll c;
}e[maxn];
ll ans;
int sz[maxn];
int head[maxn];
int tot;
void init()
{
memset(head,-,sizeof(head));
memset(sz,,sizeof(sz));
tot=;
} void add(int u,int v,ll c)
{
e[tot].to=v;
e[tot].nxt=head[u];
e[tot].c=c;
head[u]=tot++;
} int DFS(int u,int pa)
{
sz[u]=;
for(int i=head[u];i!=-;i=e[i].nxt)
{
int v=e[i].to;
ll c=e[i].c;
if(v==pa) continue;
sz[u]+=DFS(v,u);
ll cnt=min(sz[v],k);
ans+=cnt*c;
}
return sz[u];
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF)
{
init();
for(int i=;i<n-;i++)
{
int u,v;
ll c;
scanf("%d%d%lld",&u,&v,&c);
add(u,v,c);
add(v,u,c);
}
ans=;
DFS(,-);
printf("%lld\n",ans);
}
return ;
}

邻接表双向边注意边数要1e6*2

【注意事项】

  • 多组数据vector要清空,不然会wa而且stackoverflow
  • 双向边要开两倍的数组,不然会RE

【构造+DFS】2017多校训练三 HDU 6060 RXD and dividing的更多相关文章

  1. 【链表】2017多校训练三 HDU 6058 Kanade's sum

    acm.hdu.edu.cn/showproblem.php?pid=6058 [题意] 给定一个排列,计算 [思路] 计算排列A中每个数的贡献,即对于每个ai,计算有ni个区间满足ai是区间中的第k ...

  2. HDU 6060 - RXD and dividing | 2017 Multi-University Training Contest 3

    /* HDU 6060 - RXD and dividing [ 分析,图论 ] | 2017 Multi-University Training Contest 3 题意: 给一个 n 个节点的树, ...

  3. HDU 6060 RXD and dividing(dfs 思维)

    RXD and dividing Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Other ...

  4. 【(好题)组合数+Lucas定理+公式递推(lowbit+滚动数组)+打表找规律】2017多校训练七 HDU 6129 Just do it

    http://acm.hdu.edu.cn/showproblem.php?pid=6129 [题意] 对于一个长度为n的序列a,我们可以计算b[i]=a1^a2^......^ai,这样得到序列b ...

  5. 【极角排序+双指针线性扫】2017多校训练七 HDU 6127 Hard challenge

    acm.hdu.edu.cn/showproblem.php?pid=6127 [题意] 给定平面直角坐标系中的n个点,这n个点每个点都有一个点权 这n个点两两可以连乘一条线段,定义每条线段的权值为线 ...

  6. 【双向bfs】2017多校训练十 HDU 6171 Admiral

    [题意] 现在给出一个三角矩阵,如果0编号的在点(x,y)的话,可以和(x+1,y),(x-1,y),(x+1,y+1),(x-1,y-1)这些点进行交换. 我们每一次只能对0点和其他点进行交换.问最 ...

  7. HDU 6060 RXD and dividing(思维+计算贡献值)

    http://acm.hdu.edu.cn/showproblem.php?pid=6060 题意: 给定一棵 n 个节点的树,1 为根.现要将节点 2 ~ n 划分为 k 块,使得每一块与根节点形成 ...

  8. HDU 6060 RXD and dividing(LCA)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6060 [题目大意] 给一个n个节点的树,要求将2-n号节点分成k部分, 然后将每一部分加上节点1, ...

  9. hdu6060[贪心+dfs] 2017多校3

    /* hdu6060[贪心+dfs] 2017多校3*/ #include <bits/stdc++.h> using namespace std; typedef long long L ...

随机推荐

  1. neo4j(图数据库)是什么?

    不多说,直接上干货! 作为一款强健的,可伸缩的高性能数据库,Neo4j最适合完整的企业部署或者用于一个轻量级项目中完整服务器的一个子集存在. 它包括如下几个显著特点: 完整的ACID支持 高可用性 轻 ...

  2. 微信环境支付宝服务窗环境app手机浏览器pc端混合判断

    //微信环境 if(userAgent.match(/micromessenger/) == 'micromessenger'){ }//支付宝服务窗环境else if(userAgent.match ...

  3. [转]VC++的类头文件

    本文转自:http://blog.csdn.net/forevertali/article/details/4370602   animal.h //在头文件中包含类的定义及类成员函数的声明 clas ...

  4. C#处理Android Audio and Video

    Video Converter for .NET (C#) FFMpeg wrapper http://www.nrecosite.com/video_converter_net.aspx Docum ...

  5. learnpythonthehardway EX41 相关

    str.count() # str.count()方法用于统计字符串里某个字符出现的次数.可选参数为在字符串搜索的开始与结束位置. # str.count(sub, start= 0,end=len( ...

  6. Python3简明教程(七)—— 字符串

    字符串是 Python 中最常用的数据类型.本节实验将会学习如何对 Python3 的字符串进行处理操作. 字符串的三种表示 可以通过几种不同的方式表示字符串.如单引号('...')或双引号(&quo ...

  7. k8s集群之master节点部署

    apiserver的部署 api-server的部署脚本 [root@mast-1 k8s]# cat apiserver.sh #!/bin/bash MASTER_ADDRESS=$1 主节点IP ...

  8. Vickers Vane Pump - How To Choose Vane Pump Parameter Specifications?

    1 rated pressure selection. The rated pressure of the vane pump products is 7MPa, 1OMPa, 16MPa, 2lMP ...

  9. python之操作excel:xlrd、xlwt、xlutiles、枚举函数enumerate()

    一.读excel: xlrd-----只能读.不能写 import xlrd book=xlrd.open_workbook(r'E:\BestTest\内容\名单.xlsx') #打开excel s ...

  10. [BZOJ3940]:[Usaco2015 Feb]Censoring(AC自动机)

    题目传送门 题目描述: FJ把杂志上所有的文章摘抄了下来并把它变成了一个长度不超过105的字符串S.他有一个包含n个单词的列表,列表里的n个单词记为t1…tN.他希望从S中删除这些单词.FJ每次在S中 ...