以POJ - 2631为例,求树的直径和路径上的点,这里采用两次dfs的方法
#include<bits/stdc++.h>
#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define INF 0x3f3f3f3f
typedef long long ll;
const int maxn = 1e5+5;
using namespace std;
int cnt,head[maxn];
struct e
{
int to;
int w;
int next;
}edge[maxn*2];
void add(int from, int to, int w)
{
edge[++cnt].to=to;
edge[cnt].w=w;
edge[cnt].next=head[from];
head[from]=cnt;
}
int start,end_node;
int max_val,max_node,st;
int dis[maxn],path[maxn],f[maxn],top;
void dfs(int x, int fa)
{
for (int i=head[x]; i; i=edge[i].next)
{
int y=edge[i].to;
if (y==fa) continue;
dis[y]=dis[x]+edge[i].w;
if (dis[y]>max_val)
{
max_val=dis[y];
max_node=y;
}
dfs(y,x);
}
}
void dfs1(int x, int fa)
{
f[x]=fa;
for (int i=head[x]; i; i=edge[i].next)
{
int y=edge[i].to;
if (y==fa) continue;
dfs1(y,x);
}
}
void dfs2(int x)
{
if (x==0) return;
path[++top]=x;
dfs2(f[x]);
}
int solve() //求直径的长度
{
start=end_node=0;
max_val=max_node=0;
dfs(1,0);
start=st=max_node;
max_val=max_node=0;
memset(dis,0,sizeof(dis));
dfs(st,0);
end_node=max_node;
return max_val;
}
void solve_path() //求直径上的点
{
dfs1(start,0);
dfs2(end_node);
}
int main()
{
FAST;
int x,y,w;
while(cin>>x>>y>>w)
{
add(x,y,w);
add(y,x,w);
}
int ans=solve();
solve_path();
for (int i=1; i<=top; i++) cout<<path[i]<<' ';
cout<<endl;
cout<<ans<<endl;
return 0;
}