首页 > 其他分享 >NOI2003 逃学的小孩 题解

NOI2003 逃学的小孩 题解

时间:2024-08-20 18:07:30浏览次数:4  
标签:fa 题解 ll stop 逃学 dfs start NOI2003 dis

NOI2003 逃学的小孩 题解

传送门。

题目简述

给定一棵树 \(T\),需要选择三个点 \(A,B,C\),需要从 \(C\) 走到 \(A,B\)​​ 的最远距离。

(第一段题目是在讲剧情吗。。)

前置知识

  • 树的直径

思路简述

这题在蓝题(提高+ / 省选-)中还是比较水的 ^_^

来看看样例吧

瞪眼法(——数学老师) 看看,发现 \(A,B\) 可以设在 \(1\) 和 \(4\),然后 \(C\) 在 \(2\) 或 \(3\) 都无所谓。

那么 \(4\) 是咋来的呢?

(设 \(C\) 在 \(2\))

\(2\rightarrow 1 \rightarrow4\)。

由于是最远距离,那么——

树的直径!

而刚好,树的直径就是有两个端点,刚刚好可以一个作为 \(A\),一个作为 \(B\)。

然后 \(C\) 就是在除了 \(A,B\) 的节点,距离 \(A,B\) 的最短路径。

那么,直接枚举所有 \(C\),取最大值再加上 \(A\rightarrow B\) 的距离(直径距离)即可。

代码实现

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=2e5+5;
ll n,m,head[N],cnt_e,u,v,w,top,dis_start[N],dis_stop[N],start,stop,ans,ans2;
struct E{
	ll from,to,w,pre;
}e[N<<1];
inline void add(ll from,ll to,ll w)//链式前向星
{
	e[++cnt_e].from=from;
	e[cnt_e].to=to;
	e[cnt_e].w=w;
	e[cnt_e].pre=head[from];
	head[from]=cnt_e;
	return;
}
void dfs_d(ll u/*当前节点*/,ll fa/*他爹*/,ll sum/*目前的最长路径*/)//求树的直径
{
	if(sum>ans)
		ans=sum,top=u;
	for(ll i=head[u];i;i=e[i].pre)
	{
		ll v=e[i].to;
		if(v==fa) continue;
		dfs_d(v,u,sum+e[i].w);
	}
	return;
}
void dfs_dis_start(int u,int fa)//所有点到某个端点的距离
{
	for(ll i=head[u];i;i=e[i].pre)
	{
		ll v=e[i].to;
		if(v==fa) continue;
		dis_start[v]=dis_start[u]+e[i].w;
		dfs_dis_start(v,u);
	}
	return;
}
void dfs_dis_stop(int u,int fa)//所有点到另一个端点的距离
{
	for(ll i=head[u];i;i=e[i].pre)
	{
		ll v=e[i].to;
		if(v==fa) continue;
		dis_stop[v]=dis_stop[u]+e[i].w;
		dfs_dis_stop(v,u);
	}
	return;
}
signed main(){
	scanf("%lld%lld",&n,&m);
	for(ll i=1;i<=m;i++)
	{
		scanf("%lld%lld%lld",&u,&v,&w);
		add(u,v,w);add(v,u,w);
	}
	dfs_d(1,0,0);
	start=top;ans=0;
	dfs_d(start,0,0);
	stop=top;
	dfs_dis_start(start,0);
	dfs_dis_stop(stop,0);
	for(ll i=1;i<=n;i++)//枚举所有可能的C
		ans2=max(ans2,min(dis_start[i],dis_stop[i]));
	printf("%lld\n",ans+ans2);
    //ans:直径距离
    //ans2:某个点到两个端点的最短距离
	return 0;
}

小彩蛋

我:不对劲,有问题:

\(1\le T_i \le 10^9\)

十亿分钟。。。先不说你能不能活到那时候,就算能考试貌似就已经结束了吧。。

标签:fa,题解,ll,stop,逃学,dfs,start,NOI2003,dis
From: https://www.cnblogs.com/Atserckcn/p/18369995

相关文章

  • 题解:CF991D Bishwock
    思路考虑贪心。从左往右扫,找到一个就标记一个即可。但是要注意,当遇见这种情况时000000最优的方法是左右各放一个积木,共放入两块。但如果按照刚刚的方法,则有可能会是这样0X0XX0所以在一些地方有多种放法时,应该优先放置开口朝右的积木。ACCode#include<bits/stdc++.h>......
  • 题解:AT_abc365_c [ABC365C] Transportation Expenses
    题意已知\[\sum_{i=1}^{n}\min(x,a_i)\lem\]问\(x\)最大为多少。思路由于答案具有单调性,所以考虑二分答案。但是有一点要注意,当\(\sum_{i=1}^{n}a_i\lem\)时,应该输出infinite。因为此时的\(x\)可以为任意一个数。ACcode#include<bits/stdc++.h>#defineintun......
  • 题解:CF997A Convert to Ones
    题意给定一个长度为\(n\)的01字符串,有以下两种操作:将一个子串翻转,花费\(X\)将一个子串进行取反,花费\(Y\)求把原字符串变为全是\(1\)的字符串的最小代价。思路只有\(2\)操作的情况下贪心策略。考虑到任意范围取反的花费相同,我们可以将相同的部分合并,如下图合并......
  • 题解:P10696 [SNCPC2024] 写都写了,交一发吧
    前置知识位运算按位与的运算规则:二进制下,相同位的两个数字都为\(1\),则为\(1\);若有一个不为\(1\),则为\(0\)。分析由按位与的运算规则可以得到:\(A\&A=A\),而题目中的两次提交可以是相同的,所以两次都只需要取\(n\)个数中最大的数即可。ACcode#include<bits/stdc++.h>us......
  • 题解:UVA486 English-Number Translator
    这是一道模拟题。前置知识数级思路当读取到了thousand和million时,计数器要乘上对应的值并累加到最终答案里,并且把计数器归零(因为该数级已经计算完了)。当读取到hundred时,只要计数器乘上\(100\)。否则如果是其他数,则直接累加到计数器即可。ACcode#include<bits/st......
  • 题解:P10722 [GESP202406 六级] 二叉树
    思路朴素做法当输入\(a_i\)后,直接将它及它的子树进行变换。而这样时间会超时。预计得分\(40\)pts。正解统计每次变换的节点编号,第\(i\)个节点作为根节点进行子树变换的次数为\(rec_i\)。最后从这棵树的根节点\(1\)开始向下dfs,则每个节点变换的次数为\[rec_i+k_j\]......
  • 题解:UVA12398 NumPuzz I
    题意给你一个操作顺序,每个字母代表一个格子的操作。每次操作都会将一个格子及它相邻的格子的值\(-1\),如果格子的值为\(0\),则会变成\(9\)。已知操作完成后的所有格子值都为\(0\),求最开始每个格子的值为多少。思路模拟过程。倒推出得出答案。如果原操作\(-1\),那么现操作在......
  • 题解:UVA13026 Search the Khoj
    题意&翻译输入\(T\)组数据,每行数据有\(n\)个电话号码,最后再输入一行电话号码\(t\)。输出前面与\(t\)相差不超过一个字符的电话号码。思路把前面的\(n\)个电话号码逐个与\(t\)比较即可。ACcode#include<bits/stdc++.h>usingnamespacestd;intT,n;stringm[10......
  • 题解:P8887 [DMOI-R1] 柯基棋
    本题题意小A和小B在一个\(n\timesn\)的棋盘里下柯基棋,当一个人不能再放下棋子时,他就输了。问谁会有必胜策略。思路先不考虑小C的捣乱。分类讨论当\(n\)为奇数时,不难得出:当小A第一步放在棋盘的正中心时,以后不管小B放在哪里,小A只要放在它的对称处就行了。这......
  • 题解:CF644A Parliament of Berland
    本题题意有\(n\)个议员,编号为\(1\simn\),就坐在\(a\timesb\)的礼堂里,求如何安排座位能够使得任意两个相邻的座位上的议员奇偶性不相同。思路无解情况当\(n>a\timesb\)时,必定无法满足,则直接输出-1。有解情况打表找规律。我们发现,只要让奇数行正着就坐,偶数......