【】树的直径与重心
作者:互联网
树的直径
\(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);
}
标签:diameter,head,重心,int,tot,edge,dfs,直径 来源: https://www.cnblogs.com/bikuhiku/p/diameter_centroid.html