题意:给一棵树,找出$k$个点$A_{1\cdots k}$以最小化$\begin{align*}\sum\limits_{i=1}^{k-1}dis_{A_i,A_{i+1}}\end{align*}$

当$k=n$时,除了$A_1\rightarrow A_k$路径上的边,其他边都被经过两次,所以答案就是边权和的两倍减去直径长度

所以我们这样设计状态:$g_{i,j}$表示在$i$的子树内选了$j$个点(包括$i$)构成的树的(边权和的两倍)的最小值,$f0_{i,j}$表示在$i$的子树内选了$j$个点,并且这$j$个点构成的树的直径有一端是$i$,构成的树的(边权和的两倍减去直径长度)的最小值,$f1_{i,j}$表示在$i$的子树内选了$j$个点,并且这$j$个点构成的树的直径两端都不是$i$,构成的树的(边权和的两倍减去直径长度)的最小值,容易得到转移(假设$y$是$x$的儿子)

$g_{x,j+k}\leftarrow g_{x,j}+g_{y,k}+2w_{x,y}$

$f0_{x,j+k}\leftarrow f0_{x,j}+g_{y,k}+2w_{x,y}$(直径不变)

$f0_{x,j+k}\leftarrow g_{x,j}+f0_{y,k}+w_{x,y}$(直径变为从$y$过来)

$f1_{x,j+k}\leftarrow g_{x,j}+f1_{y,k}+2w_{x,y}$(直径变为从$y$来,不经过$x$)

$f1_{x,j+k}\leftarrow f0_{x,j}+f0_{y,k}+w_{x,y}$(直径变为从$y$来,经过$x$)

$f1_{x,j+k}\leftarrow f1_{x,j}+g_{y,k}+2w_{x,y}$(直径不变)

总的计算次数是$\begin{align*}\sum\limits_{fa_i=fa_j}size_isize_j\end{align*}$,注意到$\begin{align*}\sum\limits_{fa_i=fa_j=x}size_isize_j\end{align*}$统计的是$lca_{i,j}=x$的对数,对所有$x$求和就是统计点对,所以总时间复杂度是$O\left(n^2\right)$

#include<stdio.h>
const int inf=1000000000;
int h[3010],nex[6010],to[6010],w[6010],siz[3010],g[3010][3010],f0[3010][3010],f1[3010][3010],M;
void add(int a,int b,int c){
	M++;
	to[M]=b;
	w[M]=c;
	nex[M]=h[a];
	h[a]=M;
}
void min(int&a,int b){
	if(b<a)a=b;
}
void dfs(int fa,int x){
	int i,j,k,s;
	siz[x]=1;
	for(i=h[x];i;i=nex[i]){
		if(to[i]!=fa){
			dfs(x,to[i]);
			siz[x]+=siz[to[i]];
		}
	}
	g[x][1]=f0[x][1]=f1[x][1]=0;
	for(i=2;i<=siz[x];i++)g[x][i]=f0[x][i]=f1[x][i]=inf;
	s=1;
	for(i=h[x];i;i=nex[i]){
		if(to[i]!=fa){
			for(j=s;j>0;j--){
				for(k=1;k<=siz[to[i]];k++){
					min(g[x][j+k],g[x][j]+g[to[i]][k]+2*w[i]);
					min(f0[x][j+k],f0[x][j]+g[to[i]][k]+2*w[i]);
					min(f0[x][j+k],g[x][j]+f0[to[i]][k]+w[i]);
					min(f1[x][j+k],g[x][j]+f1[to[i]][k]+2*w[i]);
					min(f1[x][j+k],f0[x][j]+f0[to[i]][k]+w[i]);
					min(f1[x][j+k],f1[x][j]+g[to[i]][k]+2*w[i]);
				}
			}
			s+=siz[to[i]];
		}
	}
}
int main(){
	int n,k,i,x,y,z,ans;
	scanf("%d%d",&n,&k);
	for(i=1;i<n;i++){
		scanf("%d%d%d",&x,&y,&z);
		add(x,y,z);
		add(y,x,z);
	}
	dfs(0,1);
	ans=inf;
	for(i=1;i<=n;i++){
		if(siz[i]>=k){
			min(ans,f0[i][k]);
			min(ans,f1[i][k]);
		}
	}
	printf("%d",ans);
}

[xsy2724]Tree的更多相关文章

  1. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  2. SAP CRM 树视图(TREE VIEW)

    树视图可以用于表示数据的层次. 例如:SAP CRM中的组织结构数据可以表示为树视图. 在SAP CRM Web UI的术语当中,没有像表视图(table view)或者表单视图(form view) ...

  3. 无限分级和tree结构数据增删改【提供Demo下载】

    无限分级 很多时候我们不确定等级关系的层级,这个时候就需要用到无限分级了. 说到无限分级,又要扯到递归调用了.(据说频繁递归是很耗性能的),在此我们需要先设计好表机构,用来存储无限分级的数据.当然,以 ...

  4. 2000条你应知的WPF小姿势 基础篇<45-50 Visual Tree&Logic Tree 附带两个小工具>

    在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C# 和 2,0 ...

  5. Leetcode 笔记 110 - Balanced Binary Tree

    题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...

  6. Leetcode 笔记 100 - Same Tree

    题目链接:Same Tree | LeetCode OJ Given two binary trees, write a function to check if they are equal or ...

  7. Leetcode 笔记 99 - Recover Binary Search Tree

    题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...

  8. Leetcode 笔记 98 - Validate Binary Search Tree

    题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...

  9. Leetcode 笔记 101 - Symmetric Tree

    题目链接:Symmetric Tree | LeetCode OJ Given a binary tree, check whether it is a mirror of itself (ie, s ...

随机推荐

  1. JMeter学习笔记(四) HTTP Cookies 管理器

    有些接口执行时,要求要先登录,此时就需要用到 HTTP Cookies 管理器.不过有些项目是使用的token,即添加HTTP信息头管理器,获取登录后的token,至于token与cookies的区别 ...

  2. finally在return之后还是之前运行

    finally在运行前打印出来是return的数据,finally是最后修改的数据,如果finally存在对返回值的修改,则以finally修改的值为准. 综上所述,finally最后运行.

  3. Edu 0空投合约源码

    https://etherscan.io/address/0xa0872ee815b8dd0f6937386fd77134720d953581#code pragma solidity ^0.4.18 ...

  4. 大图轮播js

    <!DOCTYPE html><html> <head>        <meta charset="UTF-8">         ...

  5. pytorch:EDSR 生成训练数据的方法

    Pytorch:EDSR 生成训练数据的方法 引言 Winter is coming 正文 pytorch提供的DataLoader 是用来包装你的数据的工具. 所以你要将自己的 (numpy arr ...

  6. 用树莓派做3G无线路由器

    第一篇博客献给我做了很长时间的课程设计,也就是题目所说的3G无线路由器.本次开发所使用的开发平台为树莓派开发板,下面进入正题..... 目标:将树莓派设置成为一个3G无线路由器,通过华为的E261拨号 ...

  7. CF 1103B Game with modulo

    题目 $a, x$ 是正整数.显然有 \begin{aligned} x \ge 2x \pmod{a} \implies a \le 2x \end{aligned} 若 $x \le a$ 则 \ ...

  8. HDU - 5919 Sequence II

    题意: 给定长度为n的序列和q次询问.每次询问给出一个区间(L,R),求出区间内每个数第一次出现位置的中位数,强制在线. 题解: 用主席树从右向左的插入点.对于当前点i,如果a[i]出现过,则把原位置 ...

  9. vue嵌套路由与404重定向实现方法分析

    第一部分: vue嵌套路由 嵌套路由是什么? 嵌套路由就是在一个被路由过来的页面下可以继续使用路由,嵌套也就是路由中的路由的意思. 比如在vue中,我们如果不使用嵌套路由,那么只有一个<rout ...

  10. POJ2175:Evacuation Plan(消负圈)

    Evacuation Plan Time Limit: 1000MSMemory Limit: 65536KTotal Submissions: 5665Accepted: 1481Special J ...