C 小A与欧拉路 牛客练习赛40 树的直径

题解

首先考虑欧拉回路的情况,由于所给的图是一棵树则如果想构成欧拉回路就需要将每条边都复制一份
但是题目没要求回到出发点,则可以只从一个点出发到另一个点结束,所走路径也就是少了从出发点到终止点的路径
这个路径可以自己选择,则选择所给树形图中权值长度最大的两个点收益最大,也就是树的直径
树的直径使用两次DFS可以得到。

AC代码

#include <stdio.h>
#include <bits/stdc++.h>
#define fst first
#define sed second
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 4e5 + 10;
int h[MAXN], idx;

struct edge
{
	int v, w, nxt;
}e[MAXN];
void AddEdge(int u, int v, int w)
{
	e[++idx] = { v, w, h[u] }; //前++编号从1到n 循环判断非0即可不用初始化-1
	h[u] = idx;
}
pair<int, ll> DFS(int x, int f)
{
	ll mx = 0;
	int k = x;
	for (int i = h[x]; i; i = e[i].nxt)
	{
		int y = e[i].v;
		if (y != f)
		{
			pair<int, ll> res = DFS(y, x);
			if (res.sed + e[i].w > mx)
				mx = res.sed + e[i].w, k = res.fst;
		}
	}
	return{ k, mx };
}
int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
#endif
	int n;
	cin >> n;
	ll s = 0;
	for (int i = 1; i < n; i++)
	{
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		AddEdge(u, v, w);
		AddEdge(v, u, w);
		s += w * 2;
	}
	pair<int, ll> res = DFS(1, 0);
	res = DFS(res.fst, 0); //两次DFS求树的直径
	cout << s - res.sed << endl; //边权和2倍-树的直径

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值