Description
给你一棵树,求树上一个点到任意两个非这个节点的节点的距离为d1、d2,设d1 < d2,求d1*2+d2的最大值。
Sample Input
4 3
1 2 1
2 3 1
3 4 1
Sample Output
4
你考虑维护一个节点的最长链d1,次长链d2,次次长链d3,且这几条链不在同一个子树。
那其实一个点的影响其实是d1+d2*2+d3。
然后就O(n)做。。。
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
typedef long long LL;
LL _max(LL x, LL y) {return x > y ? x : y;}
LL _min(LL x, LL y) {return x < y ? x : y;}
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline void write(LL x)
{
if(!x) return (void)puts("0");
if(x<0) putchar('-'),x=-x;
static short s[25],t;
while(x) s[++t]=x%10,x/=10;
while(t) putchar('0'+s[t--]);
putchar('\n');
}
struct node {
int x, y, d, next;
} e[410000]; int len, last[210000];
LL maxx[210000], nmax[210000], dmax[210000], ll[210000];
void ins(int x, int y, int d) {
e[++len].x = x; e[len].y = y; e[len].d = d;
e[len].next = last[x]; last[x] = len;
}
void dfs1(int x, int fa) {
for(int k = last[x]; k; k = e[k].next) {
int y = e[k].y;
if(fa != y) {
dfs1(y, x);
if(maxx[y] + e[k].d >= maxx[x]) {
dmax[x] = nmax[x];
nmax[x] = maxx[x];
maxx[x] = maxx[y] + e[k].d;
}
else if(nmax[x] <= maxx[y] + e[k].d) {
dmax[x] = nmax[x];
nmax[x] = maxx[y] + e[k].d;
}
else if(dmax[x] < maxx[y] + e[k].d) {
dmax[x] = maxx[y] + e[k].d;
}
else if(nmax[y] + e[k].d >= nmax[x]) {
dmax[x] = nmax[x];
nmax[x] = maxx[y] + e[k].d;
}
else if(dmax[x] < nmax[y] + e[k].d) {
dmax[x] = nmax[y] + e[k].d;
}
}
}
}
void dfs2(int x, int fa) {
for(int k = last[x]; k; k = e[k].next) {
int y = e[k].y;
if(fa != y) {
if(maxx[y] + e[k].d == maxx[x]) ll[y] = nmax[x] + e[k].d;
else ll[y] = maxx[x] + e[k].d;
if(ll[y] >= maxx[y]) {
dmax[y] = nmax[y];
nmax[y] = maxx[y];
maxx[y] = ll[y];
}
else if(nmax[y] <= ll[y]) {
dmax[y] = nmax[y];
nmax[y] = ll[y];
}
else if(dmax[y] < ll[y]) dmax[y] = ll[y];
dfs2(y, x);
}
}
}
int main() {
int n = read(), m = read();
for(int i = 1; i <= m; i++) {
int x = read(), y = read(), c = read();
ins(x, y, c); ins(y, x, c);
}
dfs1(1, 0);
dfs2(1, 0);
LL ans = 0;
for(int i = 1; i <= n; i++) ans = _max(ans, nmax[i] * 2 + maxx[i] + dmax[i]);
write(ans);
return 0;
}