【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=6060

【题目大意】

  给一个n个节点的树,要求将2-n号节点分成k部分,
  然后将每一部分加上节点1,求每个集合最小斯坦纳树的最大权值和。

【题解】

  我们按照后序遍历染色分组,得到的一定是最优分组,
  现在考虑在不同颜色的虚树上求路径权值和,
  我们发现每个点增加的权值是深度减去到根的路径上已被覆盖的长度,
  这个长度等于与dfs序前继的LCA的深度,因此我们在搜索的同时计算与dfs序前继的LCA即可。

  But,发现多校题解完全不是我想的这样子。对于每条边来说,他的贡献值是min(k,size),然后dfs一遍即可,实现也很是简单。

  Amazing

【代码】

#include <cstdio>
#include <algorithm>
#include <list>
#include <vector>
using namespace std;
const int N=1000010;
typedef long long LL;
LL d[N];
int f[N],lst[N],c[N],st[N],en[N],dfn,size[N],son[N];
vector<int> v[N],w[N];
namespace fastIO{
#define BUF_SIZE 100000
bool IOerror=0;
inline char nc(){
static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
if(p1==pend){
p1=buf;
pend=buf+fread(buf,1,BUF_SIZE,stdin);
if(pend==p1){
IOerror=1;
return -1;
}
}return *p1++;
}
inline bool blank(char ch){
return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';
}
inline bool read(int &x){
char ch;
while(blank(ch=nc()));
if(IOerror)return false;
for(x=ch-'0';(ch=nc())>='0'&&ch<='9';x=x*10+ch-'0');
return true;
}
#undef BUF_SIZE
};
int n,m,x,y,z;
int cnt,D[N],top[N];
LL ans;
void dfs(int x){
size[x]=1;
for(int i=0;i<v[x].size();i++){
int y=v[x][i];
if(y==f[x])continue;
f[y]=x; D[y]=D[x]+1;
dfs(y); size[x]+=size[y];
if(size[y]>size[son[x]])son[x]=y;
}cnt++;
if(cnt>m)cnt=1;
c[x]=cnt;
}
void dfs1(int x,int y){
if(x==-1)return;
st[x]=++dfn; top[x]=y;
if(son[x])dfs1(son[x],y);
for(int i=0;i<v[x].size();i++)if(v[x][i]!=son[x]&&v[x][i]!=f[x])dfs1(v[x][i],v[x][i]);
en[x]=dfn;
}
int lca(int x,int y){
for(;top[x]!=top[y];x=f[top[x]])if(D[top[x]]<D[top[y]]){int z=x;x=y;y=z;}
return D[x]<D[y]?x:y;
}
void dfs2(int x){
int cx=c[x];
if(lst[cx]){
int y=lst[cx];
y=lca(x,y);
ans+=d[x]-d[y];
}else ans+=d[x];
lst[cx]=x;
for(int i=0;i<v[x].size();i++){
int y=v[x][i],z=w[x][i];
//printf("--%d %d\n",y,z);
if(y==f[x])continue;
d[y]=d[x]+z;
dfs2(y);
}
}
using namespace fastIO;
int main(){
while(read(n)){
read(m); ans=0;
for(int i=1;i<=n;i++)v[i].clear(),w[i].clear(),lst[i]=0,son[i]=-1;
for(int i=1;i<n;i++){
read(x); read(y); read(z);
v[x].push_back(y);
v[y].push_back(x);
w[x].push_back(z);
w[y].push_back(z);
}dfn=cnt=0;
dfs(1); c[1]=0;
dfs1(1,1);
dfs2(1);
printf("%lld\n",ans);
}return 0;
}

HDU 6060 RXD and dividing(LCA)的更多相关文章

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

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

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

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

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

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

  4. HDU 6060:RXD and dividing(DFS)

    题目链接 题意 给出n个点,要把除1以外的点分成k个集合,然后对于每个集合要和1这个点一起求一个最小生成树,然后问这k个最小生成树的最大总和是多少. 思路 因为每个集合都包含1这个点,因此对于每个点都 ...

  5. 【构造+DFS】2017多校训练三 HDU 6060 RXD and dividing

    acm.hdu.edu.cn/showproblem.php?pid=6060 [题意] 给定一棵以1为根的树,把这颗树除1以外的结点划分为k个集合(可以有空集),把1加入划分后的集合 每个集合的结点 ...

  6. HDU 2874 Connections between cities(LCA)

    题目链接 Connections between cities LCA的模板题啦. #include <bits/stdc++.h> using namespace std; #defin ...

  7. HDU 6061 RXD and functions(NTT)

    题意 给定一个\(n​\) 次的 \(f​\) 函数,向右移动 \(m​\) 次得到 \(g​\) 函数,第 \(i​\) 次移动长度是 \(a_i​\) ,求 \(g​\) 函数解析式的各项系数,对 ...

  8. 2017 Multi-University Training Contest - Team 3 RXD and dividing(树)

    题解: 其实贪心地算就可以了 一个最优的分配就是每条边权贡献的值为min(k, sz[x]),sz[x]是指子树的大小 然后最后加起来就是答案. #include <iostream> # ...

  9. 洛谷P3379 【模板】最近公共祖先(LCA)

    P3379 [模板]最近公共祖先(LCA) 152通过 532提交 题目提供者HansBug 标签 难度普及+/提高 提交  讨论  题解 最新讨论 为什么还是超时.... 倍增怎么70!!题解好像有 ...

随机推荐

  1. Codeforces Round #478 (Div. 2)

    题目链接:http://codeforces.com/contest/975 A. Aramic script time limit per test:1 second memory limit pe ...

  2. Python学习笔记 - day11 - Python操作数据库

    MySQL的事务 MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关,MySQL的两种引擎如下: 1.MyISAM:不支持事务,用于只读程序提高性能 2.InnoDB:支持ACID ...

  3. 【转】C++多继承的细节

    这几天写的程序应用到多继承. 以前对多继承的概念非常清晰,可是很久没用就有点模糊了.重新研究一下,“刷新”下记忆. 假设我们有下面的代码: #include <stdio.h> class ...

  4. free函数在操作系统内存中的实现【转】

    转自:http://www.2cto.com/kf/201210/160985.html 我一次性malloc十个单位节点的内存空间出来赋值给L, 现在我想一次性删除从第3个到第6个节点,我是这么做的 ...

  5. 64_c1

    CBFlib-0.9.5.15-3.fc26.i686.rpm 05-Feb-2017 21:55 427710 CBFlib-0.9.5.15-3.fc26.x86_64.rpm 05-Feb-20 ...

  6. CentOS下配置FTP

    http://www.cnblogs.com/zhenmingliu/archive/2012/04/25/2470646.html 常见错误: 1.FTP服务器已经拒绝 解决方案 # setenfo ...

  7. 数据库SQL实战(1)

    1.查找最晚入职员工的所有信息: CREATE TABLE `employees` ( `emp_no` int(11) NOT NULL, `birth_date` date NOT NULL, ` ...

  8. NOI openjudge 1792.迷宫

    一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由n * n的格点组成,每个格点只有2种状态,.和#,前者表示可以通行后者表示不能通行.同时当Extense处在某个格点时,他只 ...

  9. 多路复用I/O模型poll() 模型 代码实现

    多路复用I/O模型poll() 模型 代码实现 poll()机制和select()机制是相似的,都是对多个描述符进行轮询的方式. 不同的是poll()没有描述符数目的限制. 是通过struct pol ...

  10. Docker概览

    Docker.xmind下载