https://www.luogu.org/problem/show?pid=4408
求
m a x { d i s [ A ] [ B ] + m i n ( d i s [ B ] [ C ] , d i s [ A ] [ C ] ) } max\{dis[A][B]+min(dis[B][C],dis[A][C])\} max{dis[A][B]+min(dis[B][C],dis[A][C])}
m a x { d i s [ A ] [ B ] } max\{dis[A][B]\} max{dis[A][B]}这个用树的直径
m i n ( d i s [ B ] [ C ] , d i s [ A ] [ C ] ) min(dis[B][C],dis[A][C]) min(dis[B][C],dis[A][C])这个暴力
#include
#include
#include
#define ri register int
using namespace std;int n,m,l[200001],p,q,tot,pr[200001];
struct node{int next,to,w;}e[400001];
inline void add(ri u,ri v,ri w){e[++tot]=(node){l[u],v,w};l[u]=tot;return;}
long long Ans,ans,dis[200001],f[200001];
inline char Getchar()
{
static char buf[100000],*p1=buf+100000,*pend=buf+100000;
if(p1==pend)
{
p1=buf; pend=buf+fread(buf,1,100000,stdin);
if (pend==p1) return -1;
}
return *p1++;
}
inline long long read()
{
char c;int d=1;long long f=0;
while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline void write(register long long x)
{
if(x<0)write(45),x=-x;
if(x>9)write(x/10);
putchar(x%10+48);
return;
}
inline void dp(ri x,ri fa)//求树的直径
{
for(ri i=l[x];i;i=e[i].next)
{
int y=e[i].to;
if(y==fa) continue;
dp(y,x);
if(f[x]+f[y]+e[i].w>ans)
{
ans=f[x]+f[y]+e[i].w;
p=pr[x];q=pr[y];//保存
}
if(f[y]+e[i].w>f[x])
{
f[x]=f[y]+e[i].w;
pr[x]=pr[y];//连接
}
}
}
inline void dfs(ri x,ri fa,long long s)//暴力求距离
{
dis[x]=min(s,dis[x]);
for(ri i=l[x];i;i=e[i].next)
{
int y=e[i].to;
if(y==fa) continue;
dfs(y,x,s+e[i].w);
}
}
signed main()
{
n=read();m=read();
for(ri i=1;i<=n;i++) pr[i]=i,dis[i]=1e18;
for(ri i=1,x,y,w;i<=m;i++) x=read(),y=read(),w=read(),add(x,y,w),add(y,x,w);
dp(1,0);dfs(p,0,0);dfs(q,0,0);
for(ri i=1;i<=n;i++) Ans=max(Ans,dis[i]);
write(Ans+ans);
}