HDU 6060 17多校3 RXD and dividing(树+dfs)
Define f(S) as the the cost of the minimal Steiner Tree of the set S on tree T.
he wants to divide 2,3,4,5,6,…n into k parts S1,S2,S3,…Sk,
where ⋃Si={2,3,…,n} and for all different i,j , we can conclude that Si⋂Sj=∅.
Then he calulates res=∑ki=1f({1}⋃Si).
He wants to maximize the res.
1≤k≤n≤106
the cost of each edge∈[1,105]
Si might be empty.
f(S) means that you need to choose a couple of edges on the tree to make all the points in S connected, and you need to minimize the sum of the cost of these edges. f(S) is equal to the minimal cost
For each test case, the first line consists of 2 integer n,k, which means the number of the tree nodes , and k means the number of parts.
The next n−1 lines consists of 2 integers, a,b,c, means a tree edge (a,b) with cost c.
It is guaranteed that the edges would form a tree.
There are 4 big test cases and 50 small test cases.
small test case means n≤100.
给一个k,表示有k个集合,我们需要把2,3,4,…n号节点放入集合,要保证k个集合的并集等于{2,3,4,5…n},
并且集合互不相交。(集合可以为空)
然后每次取一个集合Si与{1}求并,得到比如{1,2,3},那么tempi = f({1,2,3});f({1}并Si)的意思是把集合内的
所有点连接起来的边的权值和。最后把所有权值和相加的到答案。
最后问你能够得到最大的答案。
我们要想得到最大的答案,那么就要尽可能的去利用这些边,也就是尽可能重复计算这些边。
那么我们想,假设先从叶子节点开始,把这些叶子节点放入一个集合,那么这个集合的temp值就会把所有的边都算一遍。那么下次我们取所有叶子节点的父亲,放入一个集合,那么这个集合的temp值会把除了叶子节点到父亲的那条那边的其他所有边都算一遍。因为集合可以为空,以此类推,我们就可以得到最大的答案。但是如果遇到集合不够的情况,就把剩下的所有点加入最后一个集合。
那么有以上分析,其实就是算每条边会算多少次,比如叶子节点到父亲的那条边会算一次。其实一条边会算多少次跟某个点的所有子孙节点个数有关,就比如样例中,2号点有3个子孙节点, 那么2号点连接父节点的那条边会算3+1次。3号点有0个子孙节点,那么3号点连接父节点的那条边会算0+1次。
那么其实问题就是转化为求每个点的子孙节点个数,然后算出每条边要重复计算的次数即可。
#include<cstdio>
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
#define MAXN 1000005 struct Edge
{
int v,w;
};//Edge[u]里面存着u连接的v和这条边的权值
vector<Edge>vec[MAXN];//容器存每个u对应的v和w
int size[MAXN];//每个节点的子节点数
int weight[MAXN];//weight[v]记录v点和它父节点的边值 void dfs(int u,int pre)//u是当前点,pre是父节点
{
size[u]=;//它本身
int len=vec[u].size();
int vv;//u的子节点
for(int i=;i<len;i++)
{
vv=vec[u][i].v;
weight[vv]=vec[u][i].w;//记录v点和它父节点的边值
dfs(vv,u);
size[u]+=size[vv];
}
} int main()
{
int n,k;
while(~scanf("%d%d",&n,&k))
{
for(int i=;i<=n;i++)
{
vec[i].clear();
size[i]=;
weight[i]=;
}
Edge tmp;
for(int i=;i<=n-;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
tmp.w=w;
//tmp.v=u;
//vec[v].push_back(tmp);
tmp.v=v;
vec[u].push_back(tmp);
}
dfs(,);//深搜找出一个子树节点的个数
long long sum=;
for(int i=;i<=n;i++)//只分2-n
{
sum+=(long long)weight[i]*min(size[i],k);
}
printf("%lld\n",sum);
}
return ;
}
这种写法比较好理解,但我感觉如果遇到不是按照父子顺序给出的权值的话,这种写法就不太适合,邻接表会好一点
HDU 6060 17多校3 RXD and dividing(树+dfs)的更多相关文章
- HDU 6063 17多校3 RXD and math(暴力打表题)
		
Problem Description RXD is a good mathematician.One day he wants to calculate: ∑i=1nkμ2(i)×⌊nki−−−√⌋ ...
 - HDU 6066 17多校3 RXD's date(超水题)
		
Problem Description As we all know that RXD is a life winner, therefore he always goes out, dating w ...
 - HDU 6060 RXD and dividing(dfs 思维)
		
RXD and dividing Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Other ...
 - HDU 6140 17多校8 Hybrid Crystals(思维题)
		
题目传送: Hybrid Crystals Problem Description > Kyber crystals, also called the living crystal or sim ...
 - HDU 6143 17多校8 Killer Names(组合数学)
		
题目传送:Killer Names Problem Description > Galen Marek, codenamed Starkiller, was a male Human appre ...
 - HDU 6045 17多校2 Is Derek lying?
		
题目传送:http://acm.hdu.edu.cn/showproblem.php?pid=6045 Time Limit: 3000/1000 MS (Java/Others) Memory ...
 - HDU 6124 17多校7 Euler theorem(简单思维题)
		
Problem Description HazelFan is given two positive integers a,b, and he wants to calculate amodb. Bu ...
 - HDU 3130 17多校7  Kolakoski(思维简单)
		
Problem Description This is Kolakosiki sequence: 1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1……. This seq ...
 - HDU 6038 17多校1 Function(找循环节/环)
		
Problem Description You are given a permutation a from 0 to n−1 and a permutation b from 0 to m−1. D ...
 
随机推荐
- VMware(虚拟机) 12版安装深度linux系统
			
需要的工具: 1.VM ware workstation12虚拟机(可自行百度下载) 参考:VMware Workstation 12.5.5 官方中文正式版,下载地址:http://www.epi ...
 - LINQ  常用from
			
单个form子句string[] values = { "LINQ学习", "LINQ基本语句", "from子句", "单个fr ...
 - acl使用示例
			
declare v_count number; uprinciple varchar2(20); principle varchar2(20); begin uprinciple := ...
 - JavaScript基础(四)
			
十六.client.offset.scroll系列 1.client系列 代码如下: <!DOCTYPE html> <html> <head> <meta ...
 - oracle 变量练习
			
select ename,&column2 from scott.emp; 输入sal: /替代标量: select * from &tab: select * from ...
 - Linux Shell获取系统资源使用百分比(CentOS)
			
CPU使用率: top -b -n | | 内存使用率: free -m | grep '^-' | awk '{print $3/($3+$4)*100"%"}' IO使用率(F ...
 - ORM框架(ITDOS实战源码)
			
ORM提供了实现持久化层的另一种模式,它采用映射元数据来描述对象关系的映射,使得ORM中间件能在任何一个应用的业务逻辑层和数据库层之间充当桥梁. 如以下示例: public int GetSystem ...
 - Mysql索引引起的死锁
			
提到索引,首先想到的是效率提高,查询速度提升,不知不觉都会有一种心理趋向,管它三七二十一,先上个索引提高一下效率..但是索引其实也是暗藏杀机的... 今天压测带优化项目,开着Jmeter高并发访问项目 ...
 - mac crontab时间断内随机时间执行定时任务
			
首先需要了解crontab使用,这里不多,主要是时间断内随机时间: 然而crontab 并没有具体方法实现时间段内随机时间执行,我的办法如下: 这里测试一个例子: 执行一个数据存文件python脚本, ...
 - shell脚本学习之参数传递
			
shell之参数传递 我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n.n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推…… 实例 以 ...