Highway (树的直径 + dfs)

链接:https://ac.nowcoder.com/acm/contest/1109/H
来源:牛客网
 

时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 32768K,其他语言65536K
Special Judge, 64bit IO Format: %lld

题目描述

In ICPCCamp there were n towns conveniently numbered with 1,2,…,n1, 2, \dots, n1,2,…,n
connected with (n - 1) roads.
The i-th road connecting towns aia_iai​ and bib_ibi​ has length cic_ici​.
It is guaranteed that any two cities reach each other using only roads.

Bobo would like to build (n - 1) highways so that any two towns reach each using *only highways*.
Building a highway between towns x and y costs him δ(x,y)\delta(x, y)δ(x,y) cents,
where δ(x,y)\delta(x, y)δ(x,y) is the length of the shortest path between towns x and y using roads.

As Bobo is rich, he would like to find the most expensive way to build the (n - 1) highways.

输入描述:

The input contains zero or more test cases and is terminated by end-of-file. For each test case:

The first line contains an integer n.
The i-th of the following (n - 1) lines contains three integers aia_iai​, bib_ibi​ and cic_ici​.

* 1≤n≤1051 \leq n \leq 10^51≤n≤105
* 1≤ai,bi≤n1 \leq a_i, b_i \leq n1≤ai​,bi​≤n
* 1≤ci≤1081 \leq c_i \leq 10^81≤ci​≤108
* The number of test cases does not exceed 10.

输出描述:

For each test case, output an integer which denotes the result.

示例1

输入

复制

5
1 2 2
1 3 1
2 4 2
3 5 1
5
1 2 2
1 4 1
3 4 1
4 5 2

输出

复制

19
15

             建立一棵最大生成树树B,其中每条边a,b的距离为现在的树A上的a,b点的最短距离。

             明显能够想到树上各个点到A的直径上两个点其中之一是距离最大的。那么就选择点i和两个直径点之一的那条边就行。

#include<bits/stdc++.h>
using namespace std;
const int M = 100010;
struct fuck {
	int v; long long d;
};
vector<fuck>G[M];
long long dis[M], udis[M];
long long maxn = -1;int pos = 0;
void dfs(int x,int fa,long long dis[]) {
	for (auto v : G[x]) {
		if (v.v == fa)continue;
		dis[v.v] = dis[x] + v.d;
		if (dis[v.v] > maxn) {
			maxn = dis[v.v];
			pos = v.v;
		}
		dfs(v.v, x, dis);
	}
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int n;
	while (cin >> n) {
		for (int i = 0; i <= n; i++) 
			G[i].clear();
		for (int i = 1; i < n; i++) {
			int a, b; long long c;
			cin >> a >> b >> c;
			G[a].push_back(fuck{ b,c }); G[b].push_back(fuck{ a,c });
		}
		if (n == 1) {
			cout << 0 << "\n";
			continue;
		}
		for (int i = 0; i <= n; i++)
			dis[i] = -1;
		dis[1] = 0;
		maxn = -1, pos = 0;
		dfs(1, 0, dis);

		int zj1 = pos;
		for (int i = 0; i <= n; i++)
			dis[i] = -1;
		dis[zj1] = 0;
		maxn = -1, pos = 0;
		dfs(zj1, 0, dis);

		int zj2 = pos;
		for (int i = 0; i <= n; i++)
			udis[i] = -1;
		udis[zj2] = 0;
		maxn = -1, pos = 0;
		dfs(zj2, 0, udis);

		long long res = dis[zj2];
		for (int i = 1; i <= n; i++) {
			if (i == zj1 || i == zj2)continue;
			res += max(dis[i], udis[i]);
		}
		cout << res << "\n";
	}
	return 0;
}

                   

猜你喜欢

转载自blog.csdn.net/chenshibo17/article/details/102077391
今日推荐