其他分享
首页 > 其他分享> > 【】树的直径与重心

【】树的直径与重心

作者:互联网

树的直径

\(2dfs\)

定理:在一棵树上,从任意节点\(x\)开始进行一次 DFS,到达的距离其最远的节点\(y\)必为直径的一端。

#include <stdio.h>

const int V = 1024;
const int E = 4096;

struct EDGE {
	int t, next, w;
} edge[E];
int edge_tot, head[V];
void add_edge(int f,int t,int w) {
	edge[++edge_tot].next = head[f];
	edge[edge_tot].t = t;
	edge[edge_tot].w = w;
	head[f] = edge_tot;
}

int dis[V], side;
void dfs(int u,int p) {
	for(int i = head[u];i;i = edge[i].next) {
		int v = edge[i].t;
		if(v == p) continue;
		dis[v] = dis[u]+edge[i].w;
		if(dis[v] > dis[side]) 
			side = v;
		dfs(v,u);
	}
}

int get_diameter() {
	dfs(1,0);
	dis[side] = 0;
	dfs(side,0);
	return dis[side];
}

int n, m;
signed main() {
	scanf("%d",&n);
	for(int i = 1, a, b, c;i < n;++i) {
		scanf("%d %d %d\n",&a,&b,&c);
		add_edge(a,b,c);
		add_edge(b,a,c);
	}
	int diameter = get_diameter();
	printf("%d\n",diameter);
}

树形\(DP\)

#include <stdio.h>
#include <bits/stl_algobase.h>

const int V = 1024;
const int E = 4096;

struct EDGE {
	int t, next, w;
} edge[E];
int edge_tot, head[V];
void add_edge(int f,int t,int w) {
	edge[++edge_tot].next = head[f];
	edge[edge_tot].t = t;
	edge[edge_tot].w = w;
	head[f] = edge_tot;
}

int d1[V], d2[V], diameter;
void dfs(int u,int p) {
	d1[u] = d2[u] = 0;
	for(int i = head[u];i;i = edge[i].next) {
		int v = edge[i].t;
		if(v == p) continue;
		dfs(v,u);
		int d = d1[v]+edge[i].w;
		if(d > d1[u]) {
			d2[u] = d1[u];
			d1[u] = d;
		} else if(d > d2[u]) {
			d2[u] = d;
		}
	}
	diameter = std :: max(diameter,d1[u]+d2[u]);
}

int get_diameter() {
	dfs(1,0);
	return diameter;
}

int n, m;
signed main() {
	scanf("%d",&n);
	for(int i = 1, a, b, c;i < n;++i) {
		scanf("%d %d %d\n",&a,&b,&c);
		add_edge(a,b,c);
		add_edge(b,a,c);
	}
	int diam = get_diameter();
	printf("%d\n",diam);
}

@\(\color{black}{bikuhiku}\)

标签:diameter,head,重心,int,tot,edge,dfs,直径
来源: https://www.cnblogs.com/bikuhiku/p/diameter_centroid.html