Advance

zz: https: //blog.csdn.net/rzo_kqp_orz/article/details/52280525
small Z began ETG. ETG tree map is, a distance from the two adjacent rooms, the beginning, the system will randomly cut off an edge, so that this
map is in communication is divided into two blocks. Obviously, cunning system will be distributed in four chest twenty-two farthest point on each Unicom right. At first, small Z will be
born in the room there is a chest of (the system is still a bit of conscience), then small Z "BOOM BOOM BOOM" went all the way there is another chest of the
ground (apparently small Z take the shortest path) after reaching the second chest location, the system will very conscientious his chest at a communication to another block,
then another small Z "tapping pound", to get the last chest. Then he would pass off. Z is obviously small clearance is yes, so small Z wanted to
know how much he would walk up to a distance.

Input
input of the first row contains an integer N, the number of rooms.
Then N-1 lines of three positive integers x, y, D represents the room x and y distance of the room d.
N <= 100,000, di <= 100,000.

Output
line of output contains an integer, Z represents a small distance of the most flee.

Sample Input
6
1 3 4
2 3 1
2 5 3
2 6 2
3 4 5

Sample Output
14

Data Constraint

For 50% of the data satisfies N <= 1000.
To 100% of the data satisfies

An intended subject
is given a tree, you can select a cut off an edge, then two trees and the diameter and the produced. And seek the maximum.
[50%] n <= 1000
enumeration which a breaking edge, and then find the diameter of violence.
Method 1 [100%] n <= 10 5 ^
diameter segment tree with tree maintenance.
The combined enumeration which range off an edge, which is equivalent to the original tree isolated subtree, we can find the segment tree to tree diameter sub-tree, and then get another look at the rest of the diameter.
If required lca doubling time is O (n log ^ 2), will be stuck.
If required by rmq lca time O (log n-)
// diameter segment tree maintenance tree: http: //blog.csdn.net/rzo_kqp_orz/article/details/52280811
[100%] Method 2
question this is illustrated naked tree dp! ?
Solution of the original problem, then: "Naked tree DP, recording d1 [i] (longest chain), d2 [i] (Ci long chain), fa [i] (i father longest path and above) can be. the time complexity of O (n). "
the idea is very simple, but maintenance fight discuss more.

#include<cmath>
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

typedef long long LL;

const int maxn=(1e5)+5, MX=18;

struct TR{
    int x,y;
    LL len;

    TR (int X = 0, int y = 0, LL LEN = 0) {x = X, y = Y, len = LEN;}
};

int n;

int tot,go[2*maxn],next[2*maxn],f1[maxn];
LL val[2*maxn];
void ins(int x,int y,LL z)
{
    go[++tot]=y;
    val [up] = z;
    next[tot]=f1[x];
    f1 [x] = all;
}

int fa[2*maxn][MX+5],deep[maxn],ap[2*maxn],fir[2*maxn],Log[2*maxn],er[MX+5];
void rmq_pre()
{
    fo(i,1,ap[0]) fa[i][0]=ap[i], Log[i]=log(i)/log(2);
    fo(i,0,MX) er[i]=1<<i;
    fo(j,1,MX)
        fo(i,1,ap[0])
        {
            four [c] [j] = four [c] [j-1];
            if (i+er[j-1]<=ap[0] && deep[fa[i+er[j-1]][j-1]]<deep[fa[i][j]])
                fa [i] [j] = fa [i + er [j-1]] [j-1];
        }
}
int lca(int x,int y)
{
    for x = [x], y = a [y];
    if (x>y) swap(x,y);
    int t=Log[y-x+1];
    return (deep[fa[x][t]]<deep[fa[y-er[t]+1][t]]) ?fa[x][t] :fa[y-er[t]+1][t] ;
}

int st[maxn],en[maxn],sum,Tbh[maxn];
LL dis[maxn];
void dfs_pre(int k,int last,LL s)
{
    deep[k]=deep[last]+1;
    dis[k]=s;
    Up [++ up [0]] = A, then [a] = up [0];
    Tbh[++sum]=k, st[k]=sum;
    for(int p=f1[k]; p; p=next[p]) if (go[p]!=last)
    {
        dfs_pre(go[p],k,s+val[p]);
        Up [++ up [0]] = a;
    }
    en[k]=sum;
}

TR tr [4 * maxn];
LL DIS(int x,int y) {return dis[x]+dis[y]-dis[lca(x,y)]*2;}
Go TR (TR, TR b)
{
    TR = Re (a.len> b.len)? A: b;
    if (DIS(a.x,b.x)>re.len) re=TR(a.x,b.x,DIS(a.x,b.x));
    if (DIS(a.x,b.y)>re.len) re=TR(a.x,b.y,DIS(a.x,b.y));
    if (DIS(a.y,b.x)>re.len) re=TR(a.y,b.x,DIS(a.y,b.x));
    if (DIS (ay, b)> re.len) re = TR (ay, by, DIS (ay, b));
    return re;
}
void tr_js(int k,int l,int r)
{
    if (l==r)
    {
        p [j] .x = p [k] .y = TBH [l];
        tr [a] .len = 0;
        return;
    }
    int t=k<<1, t1=(l+r)>>1;
    tr_js(t,l,t1), tr_js(t+1,t1+1,r);
    tr [k] = go (tr [t], t R [t + 1]);
}
TR tr_cx (k you, you're, you're down, you're out, you y)
{
    if (l==x && r==y) return tr[k];
    int t=k<<1, t1=(l+r)>>1;
    if (y<=t1) return tr_cx(t,l,t1,x,y);
        else if (x>t1) return tr_cx(t+1,t1+1,r,x,y);
            else return merge (tr_cx (t, l, t1, x, t1), tr_cx (t + 1, t1 + 1, r, t1 + 1, y));
}

LL ans;
void dfs(int k,int last)
{
    for(int p=f1[k]; p; p=next[p]) if (go[p]!=last)
    {
        int St=st[go[p]], En=en[go[p]];
        if (St==1)
        {
            years = max (years tr_cx (1,1, n, St, En) .len + tr_cx (1,1, n, En + 1, n) .len);
        } Else if (n == A)
        {
            years = max (years tr_cx (1,1, n, 1, St-1) + .len tr_cx (1,1, n, St, En) .len);
        } else
        {
            TR t = merge (tr_cx (1.1 N, 1, St-1), tr_cx (1,1, n, En + 1, n));
            years = max (years t.len + tr_cx (1,1, n, St, En) .len);
        }

        dfs(go[p],k);
    }
}

int main ()
{
    scanf("%d",&n);
    fo(i,1,n-1)
    {
        int x,y; LL d;
        scanf("%d %d %lld",&x,&y,&d);
        ins(x,y,d), ins(y,x,d);
    }

    dfs_pre(1,0,0);
    rmq_pre ();
    tr_js (1,1, n);

    dfs(1,0);

    printf("%lld\n",ans);
}

#include <cstdio>
#include <cstring>
#include <algorithm>
#define i64 long long
using namespace std;

const int N = 1e5 + 10;
int n, r [N] everything;
i64 years;

struct edge{int t, l, n;} e[N * 2];

struct link {
    i64 v1, v2, v3;
    int u1, u2, u3;
    void ins(int u, i64 v) {
        if (v > v1) u3 = u2, v3 = v2, u2 = u1, v2 = v1, u1 = u, v1 = v;
        else if (v > v2) u3 = u2, v3 = v2, u2 = u, v2 = v;
        else if (v > v3) u3 = u, v3 = v;
    }
} l[N];

i64 max(i64 x, i64 y) {return x > y ? x : y;}

void add(int x, int y, int z) {
    e [++ tot] .t = y; e [tot] .l = z; e [dead] .n = r [x]; r [x] = dead;
}

void dfs(int u, int fa) {
    the [and] = the .u1 [and] = the .u2 [and] = the .v1 [and] .v2 = 0;
    for (int i = r[u]; i; i = e[i].n) {
        int v = e[i].t;
        if (v == fa) continue;
        dfs(v, u);
        i64 t = l[v].v1 + e[i].l;
        l[u].ins(v, t);
    }
}

void awn(int u, int fa, i64 ll, i64 mx) {
    for (int i = r[u]; i; i = e[i].n) {
        int v = e[i].t;
        if (v == fa) continue;
        i64 t = 0, mm = 0;
        if (l[u].u1 == v) t = l[u].v2;
        else t = l[u].v1;
        if (l[u].u1 == v) mm = l[u].v2 + l[u].v3;
        else if (l[u].u2 == v) mm = l[u].v1 + l[u].v3;
        else mm = l[u].v1 + l[u].v2;
        ans = max(ans, l[v].v1 + l[v].v2 + max(mm, max(mx, ll + t)));
        awn(v, u, max(ll, t) + e[i].l, max(mm, max(mx, ll + t)));
    }
}

int main () {
    scanf("%d", &n);
    for (int i = 1; i < n; i ++) {
        int u, v, w;
        scanf("%d %d %d", &u, &v, &w);
        add(u, v, w); add(v, u, w);
    }
    dfs(1, 0);
    awn(1, 0, 0, 0);
    printf("%lld", ans);
    return 0;
}

  

Guess you like

Origin www.cnblogs.com/cutemush/p/11831036.html
Recommended