BZOJ1999或洛谷1099&BZOJ2282或洛谷2491 树网的核&[SDOI2011]消防
一道树的直径
树网的核 BZOJ原题链接
树网的核 洛谷原题链接
消防 BZOJ原题链接
消防 洛谷原题链接
一份代码四倍经验,爽
显然要先随便找一条直径,然后直接枚举核的两个端点,对每一次枚举的核遍历核上的每个点,用\(dfs\)求出核外节点到核的最大值即可,时间复杂度为\(O(n^3)\),这在\(NOIP\)的原数据范围下是可以过的,但对于数据加强版就必须要优化了。
发现当枚举到直径上的某个点时,核的另一端在不超过\(s\)的前提下显然越远越好。这样就直接优化掉一个\(n\)了,但我们还可以继续优化。
设直径上的点为\(u_1,u_2,\dots,u_t\),当前枚举到的核的两端点为\(x_i,x_j\)。
根据直径的最长性,我们可以发现对于该核的偏心距实际上就是\(\max\{\max\limits_{k=1}^{t}\{d[u_k]\},dis(u_1,x_i),dis(x_j,u_t)\}\),数组\(d\)表示直径外节点(不经过直径上的点)到\(u_k\)的最大值,\(dis\)表示两点间的距离。
而\(\max\limits_{k=1}^{t}\{d[u_k]\}\)显然是个定值,至于\(dis\),我们可专门剖出直径上的所有边,然后用在枚举核的左端点时用两个变量维护即可,时间复杂度\(O(n)\)。
#include<cstdio>
using namespace std;
const int N = 5e5 + 10;
struct dd {
	int dis, x;
};
dd D[N], a[N];
int fi[N], di[N << 1], da[N << 1], ne[N << 1], l, ma;
bool v[N];
inline int re()
{
	int x = 0;
	char c = getchar();
	bool p = 0;
	for (; c<'0' || c>'9'; c = getchar())
		p |= c == '-';
	for (; c >= '0'&&c <= '9'; c = getchar())
		x = x * 10 + (c - '0');
	return p ? -x : x;
}
inline int maxn(int x, int y)
{
	return x > y ? x : y;
}
inline int minn(int x, int y)
{
	return x < y ? x : y;
}
inline void add(int x, int y, int z)
{
	di[++l] = y;
	da[l] = z;
	ne[l] = fi[x];
	fi[x] = l;
}
void dfs(int x, int fa, int dis, int la)
{
	int i, y;
	if (dis > ma)
	{
		ma = dis;
		D[0].x = x;
	}
	D[x].x = fa;
	D[x].dis = la;
	for (i = fi[x]; i; i = ne[i])
	{
		y = di[i];
		if (y != fa)
			dfs(y, x, dis + da[i], da[i]);
	}
}
void dfs_2(int x, int dis)
{
	int i, y;
	v[x] = 1;
	if (dis > ma)
		ma = dis;
	for (i = fi[x]; i; i = ne[i])
	{
		y = di[i];
		if (!v[y])
			dfs_2(y, dis + da[i]);
	}
}
int main()
{
	int i, j, n, m, x, y, z, s = 0, k = 0, tail = 0, head = 0, an = 1e9;
	n = re();
	m = re();
	for (i = 1; i < n; i++)
	{
		x = re();
		y = re();
		z = re();
		add(x, y, z);
		add(y, x, z);
	}
	dfs(1, 0, 0, 0);
	ma = 0;
	dfs(D[0].x, 0, 0, 0);
	for (i = D[0].x; i; i = D[i].x)
	{
		v[i] = 1;
		a[++k].x = i;
		a[k].dis = D[i].dis;
	}
	ma = 0;
	for (i = 1; i <= k; i++)
		dfs_2(a[i].x, 0);
	for (j = 1; j < n; j++)
		if (s + a[j].dis <= m)
			s += a[j].dis;
		else
			break;
	for (i = j; i < n; i++)
		tail += a[i].dis;
	an = minn(an, maxn(ma, maxn(head, tail)));
	for (i = 1; i < n; i++)
	{
		s -= a[i].dis;
		head += a[i].dis;
		for (; j < n; j++)
			if (s + a[j].dis <= m)
			{
				s += a[j].dis;
				tail -= a[j].dis;
			}
			else
				break;
		an = minn(an, maxn(ma, maxn(head, tail)));
	}
	printf("%d", an);
	return 0;
}
BZOJ1999或洛谷1099&BZOJ2282或洛谷2491 树网的核&[SDOI2011]消防的更多相关文章
- 洛谷P1099 BZOJ1999 树网的核 [搜索,树的直径]
		洛谷传送门,BZOJ传送门 树网的核 Description 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(treenetwork),其中V ... 
- [洛谷P2491] [SDOI2011]消防
		洛谷题目链接:[SDOI2011]消防 题目描述 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超 ... 
- [BZOJ1999] 树网的核 [数据加强版] (树的直径)
		传送门 如果只是想验证算法正确性这里是洛谷数据未加强版 Description 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(treenet ... 
- [BZOJ1999][codevs1167][Noip2007]Core树网的核
		[BZOJ1999][codevs1167][Noip2007]Core树网的核 试题描述 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(t ... 
- 【BZOJ2282】[Sdoi2011]消防 树形DP+双指针法+单调队列
		[BZOJ2282][Sdoi2011]消防 Description 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这 ... 
- bzoj1999 (洛谷1099) 树网的核——dfs
		题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1999 https://www.luogu.org/problemnew/show/P109 ... 
- 洛谷 1099 ( bzoj 1999 ) [Noip2007]Core树网的核
		题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1999 <算法竞赛进阶指南>346页.https://www.cnblogs.co ... 
- 洛谷1099 [NOIP2007] 树网的核
		链接https://www.luogu.org/problemnew/show/P1099 题目描述 设T=(V,E,W)是一个无圈且连通的无向图(也称为无根树),每条边到有正整数的权,我们称TTT为 ... 
- 【新知识】队列&bfs【洛谷p1996约瑟夫问题&洛谷p1451求细胞数量】
		(是时候为五一培训准备真正的技术了qwq) part1 队列(FIFO) 算法简介: FIFO:First In First Out(先进先出) 队列是限定在一端进行插入,另一端进行删除的特殊线性表 ... 
随机推荐
- Pandas数据排序
			Pandas数据排序 .sort_index() 在指定轴上根据索引进行排序,索引排序后内容会跟随排序 b = pd.DataFrame(np.arange(20).reshape(4,5),inde ... 
- Vue 中select option默认选中的处理方法
			在做泰康项目的时候有个需求就是要给select默认选中的样式我的处理方法有两个 1.直接将默认值给 selectedOption <select v-model="selectedO ... 
- Python Try Except
			Python Try: Except Except 类型一: try: file_size = os.path.getsize('maoyan.csv'); except OSError as err ... 
- linux投递运行情况
			1.构建文件夹 ..}.sh 2.状态 D 不可中断 Uninterruptible sleep (usually IO) R 正在运行,或在队列中的进程 S 处于休眠状态 T 停止或被追踪 Z 僵尸 ... 
- cdnbest节点安装后连不上cdn主控原因排查
			1. 查看节点程序是否启动 ps -aux |grep kangle 2. 登陆cdn节点用telnet命令查下和主控的通信,命令:telnet 主控ip 3320 3. 如果节点程序都有启动,可查看 ... 
- kali安装显卡驱动
			由于我们使用cpu一般最多也就是4到16核,而一块不错的gpu可以多大上千核,在并行复杂运算能力上GPU的运算速度远远超过CPU的运算速度,所以很多场合比如暴力穷举破解,挖矿更多地使用GPU,所以有必 ... 
- elastic search文档详解
			在elastic search中文档(document)类似于关系型数据库里的记录(record),类型(type)类似于表(table),索引(index)类似于库(database). 文档一定有 ... 
- SSM的例子-参考
			ssm的例子:http://blog.csdn.net/double030/article/details/63683613 
- pta_l1-6(连续因子)
			题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805138600869888 题意:给定n,求n的最长的连续子因 ... 
- 二叉树的深度优先遍历与广度优先遍历 [ C++ 实现 ]
			深度优先搜索算法(Depth First Search),是搜索算法的一种.是沿着树的深度遍历树的节点,尽可能深的搜索树的分支. 当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点 ... 
