找出直径s->t,路径一定是x->s->t或者x->t->s这样的形式。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 200050 #define maxe 400050 using namespace std; long long n,m,x,y,z,dis[maxv],mx[maxv][3],nume=1,g[maxv],pos[maxv][3],fath[maxv],root; long long ans; struct edge { long long v,w,nxt; }e[maxe]; void addedge(long long u,long long v,long long w) { e[++nume].v=v;e[nume].w=w; e[nume].nxt=g[u];g[u]=nume; } void dfs(long long x,long long father) { fath[x]=father;if (x==root) dis[x]=0; mx[x][1]=mx[x][2]=0;pos[x][1]=pos[x][2]=x; for (long long i=g[x];i;i=e[i].nxt) { long long v=e[i].v; if (v==father) continue; dis[v]=dis[x]+e[i].w; dfs(v,x); if (mx[v][1]+e[i].w>mx[x][1]) { mx[x][2]=mx[x][1];pos[x][2]=pos[x][1]; mx[x][1]=mx[v][1]+e[i].w;pos[x][1]=pos[v][1]; } else if (mx[v][1]+e[i].w>mx[x][2]) { mx[x][2]=mx[v][1]+e[i].w; pos[x][2]=pos[v][1]; } } } int main() { scanf("%lld%lld",&n,&m); for (long long i=1;i<=m;i++) { scanf("%lld%lld%lld",&x,&y,&z); addedge(x,y,z);addedge(y,x,z); } root=1;dfs(root,0); root=pos[root][1];dfs(root,0); long long ret=pos[root][1]; for (;;) { ans=max(ans,mx[ret][2]+dis[pos[root][1]]+min(mx[ret][1],dis[pos[root][1]]-mx[ret][1])); if (ret==root) break; ret=fath[ret]; } printf("%lld\n",ans); return 0; }