HDU 6613 Squrirrel tree dp

Meaning of the questions: give your tree, you can put an edge on the right side of the tree becomes 0, now lets you choose a root, so that all point to the point of maximum distance as small as possible. If more than the maximum distance from the root, the output of the minimum number of edges.

Ideas: If you do not put into action the right side of zero, this question is actually to find the center of the diameter of the tree. There are 0 becomes operational, it is easy to think of whether to raise the one-dimensional mark has the right to the edge of an edge becomes zero. We may wish to calculate the answer to 1 is the root. Set DP [i] [0] is not changed from the maximum edge weight for the subtree rooted at i, dp [i] [1] is a bar after the right Collage that path becomes longest 0 this minimum length of the longest path. We found that only know the longest path seems not enough, because right after a bar Collage longest path becomes zero may be gone a long time long path. So next time we need to maintain a long path. So when we first pass dfs dimensions needed to care about the minimum length i is the root of the subtree longest path and the second path length, and the longest path and a secondary path long after the modification. For the longest time path and long path without modification, maintenance directly on the line. So how to maintain the minimum length of the longest path modified it? We need to record what the point i i the longest path and the adjacent point j (j is the child of i), then two possibilities: 1: Delete the edge between i and j. 2: the minimum edge deletion had previously taken together with the edge weight of the edge between the points i and j. Set DP [i] [0] [1] i is a root in the longest path (0: up, 1: chief) (1: Review belt, 0: not modify) the minimum length, then the DP [i ] [0] [1] = min (dp [j] [0] [0], max (dp [j] [0] [1], dp [j] [1] [0]) + w). Minister Road Similarly available. Then we can come to is the root of the answer. ans = min (dp [1] [0] [1], dp [1] [1] [0]). Now consider other points calculated in the root root answer by exchange method, i.e., the contribution from the direction of the parent node of the answers. We consider the impact of our parent. Set f [i] [0/1] i is the maximum length of the root to its parent node formed by the direction of the path of the (modified with / without modification), then we are in at the time i is calculated as the root of the parent answer contributions are also taken into account the direction of the node on the line, that i consider is to modify the parent node and even the edges, or modify the parent node direction side, or side to modify sub-tree? This put the answer calculated. How to maintain f [i] [0] and f [i] [1] it? The longest distance f [i] [0] affirmative direction from a parent node i and parent subtree take maximum distance i max and right sides plus the parent node. The longest distance subtree does not include i, so we transferred to special judge it. So the question is, in case our times is the point of long distance i how to do? Therefore, the equivalent of one third less maintained a long distance before us, namely the need to maintain maximum when the first pass dfs, long time, the third longest distance. f [i] [1] is the same, considering changes enumerated transferred to which edge (parent side direction, side direction subtree).

Code:

#include <bits/stdc++.h>
#define pii pair<int, int>
using namespace std;
const int maxn = 200010;
pii dp[maxn][3][2];//点, 第几远,不删边/删边
int f[maxn][2];//父亲节点来的,不删边/删边
int d[maxn];
vector<pii> G[maxn];
int ans, pos;
void add(int x, int y, int z) {
	G[x].push_back(make_pair(y, z));
	G[y].push_back(make_pair(x, z));
}
void dfs1(int x, int fa) {
	for (auto y : G[x]) {
		if(y.first == fa) continue;
		dfs1(y.first, x);
		d[y.first] = y.second;
		if(dp[y.first][0][0].first + y.second >= dp[x][0][0].first) {
			dp[x][2][0] = dp[x][1][0]; 
			dp[x][1][0] = dp[x][0][0];
			dp[x][0][0] = make_pair(dp[y.first][0][0].first + y.second, y.first);
		} else if(dp[y.first][0][0].first + y.second >= dp[x][1][0].first) {
			dp[x][2][0] = dp[x][1][0];
			dp[x][1][0] = make_pair(dp[y.first][0][0].first + y.second, y.first);
		} else if(dp[y.first][0][0].first + y.second >= dp[x][2][0].first) {
			dp[x][2][0] = make_pair(dp[y.first][0][0].first + y.second, y.first);
		}
	}
	int tmp = dp[x][0][0].second;
	dp[x][0][1].first = min(dp[tmp][0][0].first, max(dp[tmp][0][1].first, dp[tmp][1][0].first) + d[tmp]);
	tmp = dp[x][1][0].second;
	dp[x][1][1].first = min(dp[tmp][0][0].first, max(dp[tmp][0][1].first, dp[tmp][1][0].first) + d[tmp]);
}
void dfs2(int x, int fa) {
	int tmp = min(max(f[x][0], max(dp[x][0][1].first, dp[x][1][0].first)), max(f[x][1], dp[x][0][0].first));
	if(tmp < ans) {
		ans = tmp;
		pos = x;
	} else if(tmp == ans) {
		pos = min(pos, x);
	}
	for (auto y : G[x]) {
		if(y.first == fa) continue;
		if(y.first == dp[x][0][0].second) {
			f[y.first][0] = max(dp[x][1][0].first, f[x][0]) + y.second;
			f[y.first][1] = min(max(dp[x][1][0].first, f[x][0]), min(max(f[x][0], max(dp[x][1][1].first, dp[x][2][0].first)), max(dp[x][1][0].first, f[x][1])) + y.second);
		} else {
			f[y.first][0] = max(dp[x][0][0].first, f[x][0]) + y.second;
			if(dp[x][1][0].second == y.first) {
				f[y.first][1] = min(max(dp[x][0][0].first, f[x][0]), min(max(f[x][0], max(dp[x][0][1].first, dp[x][2][0].first)), max(dp[x][0][0].first, f[x][1])) + y.second);
			} else {
				f[y.first][1] = min(max(dp[x][0][0].first, f[x][0]), min(max(f[x][0], max(dp[x][0][1].first, dp[x][1][0].first)), max(dp[x][0][0].first, f[x][1])) + y.second);
			}
		}
		dfs2(y.first, x);
	}
}
int main() {
	int T, n, u, v, w;
//	freopen("in.txt", "r", stdin);
//	freopen("out.txt", "w", stdout);
	scanf("%d", &T);
	while(T--) {
		scanf("%d", &n);
		for (int i = 1; i <= n; i++) {
			G[i].clear();
			memset(dp[i], 0, sizeof(dp[i]));
			memset(f[i], 0, sizeof(f[i]));
			d[i] = 0;
		}
		for (int i = 1; i < n; i++) {
			scanf("%d%d%d", &u, &v, &w);
			add(u, v, w);
		}
		dfs1(1, 0);
		ans = max(dp[1][0][1].first, dp[1][1][0].first);
		pos = 1;
		dfs2(1, 0);
		printf("%d %d\n", pos, ans);
	}
}

  

 

Guess you like

Origin www.cnblogs.com/pkgunboat/p/11420039.html