A - 氪金带东

题意介绍

求图中各点到其他点的最大长度。

题意分析

假设图中相距最远的两个点为v1,v2则则图中任一点到其他点的最大长度不是到v1的长度就是到v2的长度,所以首要任务就是找到v1,v2。首先,dfs任意点找到v1或v2,然后从该点再次dfs找到v2或v1,遍历过程中记录各点到起点的距离,找到v2或v1后,再从该点进行一次dfs,并记录各点到起点的距离,那么图中各点的最大距离就是到v1距离和到v2距离的最大值。

通过代码

#include<iostream>
#include<algorithm>
using namespace std;

struct Edge {
	int u, v, w, next;
};

Edge edge[100000];
int head[100000], tot,s;
int d1[100000], d2[100000];
bool vis[100000];

void init(int n) {
	tot = 0;
	for (int i = 0; i < n; i++) head[i] = -1;
}

void addEdge(int u, int v, int w) {
	edge[tot].u = u;
	edge[tot].v = v;
	edge[tot].w = w;
	edge[tot].next = head[u];
	head[u] = tot;
	tot++;
}


void dfs(int u, int length, int *d) {
	d[u] = length;
	if (d[s] < d[u]) s = u;
	for (int i = head[u]; i != -1; i = edge[i].next) {
		if (!vis[edge[i].v]) {
			vis[edge[i].v] = true;
			dfs(edge[i].v, length + edge[i].w, d);
		}
	}
}

int N,v,w;

int main() {
	ios::sync_with_stdio(false);
	while (cin >> N) {
		init(N + 1);
		for (int i = 2; i <= N; i++) {
			cin >> v >> w;
			addEdge(i, v, w);
			addEdge(v, i, w);
		}

		for (int i = 1; i <= N; i++) vis[i] = 0;
		d1[s] = 0;
		vis[1] = 1;
		dfs(1, 0, d1);

		for (int i = 1; i <= N; i++) vis[i] = 0;
		d1[s] = 0;
		vis[s] = 1;
		dfs(s, 0, d1);

		for (int i = 1; i <= N; i++) vis[i] = 0;
		d2[s] = 0;
		vis[s] = 1;
		dfs(s, 0, d2);

		for (int i = 1; i <= N; i++)
			cout << max(d1[i], d2[i]) << endl;
	}
}
发布了40 篇原创文章 · 获赞 0 · 访问量 1068

猜你喜欢

转载自blog.csdn.net/weixin_44934885/article/details/105181322