0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Atcoder解いてみた AtCoder Beginner Contest E - Tree and Hamilton Path 2

0
Posted at

AtCoder Beginner Contest E - Tree and Hamilton Path 2

問題はこちら

回答

全ての点を通り、ある点にたどり着いた時の距離は、以下の図の黒線で示した経路の距離から赤線の距離を引けばいい
黒線の距離は、全ての辺の長さの和を2倍したものである
今回は、赤線の距離を最大化すればいい
そのためには、グラフの直径を求めればいい
グラフの直径を求めるには、適当な点からDFSし、最も遠い点を求め(点1)、その点からもう一度DFSし最も遠い点(点2)を求め、点1-2間の距離を求めればいい
image.png

#include <iostream>
#include <string>
#include <map>
#include <unordered_map>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <limits.h>
#include <bitset>
#include <list>
#include <set>
#include <numeric>
#include <tuple>

struct Edge {
	long long t;
	long long c;
};

struct DfsRes {
	long long p;
	long long c;
};

int N;
std::vector<std::vector<Edge>> G;

std::vector<bool> seen;


DfsRes dfs(const int& s, DfsRes dfsResP) {
	seen[s] = true;

	DfsRes tmpDfsRes = dfsResP;
	// sの隣接点を見る
	for (const Edge& e : G[s]) {
		// 隣接点が未訪問
		if (seen[e.t] == false) {
			// 隣接点にいざ訪問するときに、最長距離と最長距離をとるときの点を更新
			// DFSに区切りがつき、戻ってくることを考慮し、更新
			// 各隣接点を訪問しきった後のdfsResの中で最もいい結果を採用
			DfsRes dfsRes = dfs(e.t, { e.t, dfsResP.c + e.c });
			// dfsの再起関数を抜けると、DFSに区切りがつき、戻ってくる
			if (dfsRes.c > tmpDfsRes.c) {
				tmpDfsRes = dfsRes;
			}
		}
	}

	return tmpDfsRes;
}

int main()
{
	std::cin.tie(0);
	std::ios::sync_with_stdio(false);

	std::cin >> N;

	G.resize(N);

	long long sumCost2 = 0;
	for (int i = 1; i < N; i++) {
		int a, b;
		long long c;

		std::cin >> a >> b >> c;

		a--;
		b--;

		// 無向グラフ
		Edge e = { b,c };
		G[a].push_back(e);

		e = { a,c };
		G[b].push_back(e);

		sumCost2 += 2 * c;
	}

	// dfsを2回
	// 適当な点から最も遠い点を見つけ、その点から最も遠い点を見つける

	// 初期化・1回目
	int s = 0;
	DfsRes dfsRes = { s,0 };
	seen.resize(N);
	dfsRes = dfs(s, dfsRes);

	// 初期化・2回目
	s = dfsRes.p;
	dfsRes = { s,0 };
	std::fill(seen.begin(), seen.end(), false);
	dfsRes = dfs(s, dfsRes);
	
	long long ans = sumCost2 - dfsRes.c;
	std::cout << ans << std::endl;

	return 0;
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?