[BZOJ3242] [Noi2013] fast food restaurant && Ring set tree + line tree

Source: Internet
Author: User
Tags bool min

If it's a tree then the answer is obviously diameter/2

But now it's a ring-set tree, so you just enumerate through each side of the ring and delete it and ask for the diameter to be spicy (obviously you're not going to be on one side of the ring.)

And then you ask for the remaining diameter of the tree, and then the n^2 will explode.

We maintain the longest chain s of the tree with the nodes rooted in the ring

The two-point distance on the ring can be prefixed and processed (assuming that the first edge of the enumeration is the edge of the first and last point on the ring so that it can be prefixed and represented)

The diameter is Max (Sum[j]-sum[i]+s[i]+s[j])

Use a line tree to maintain sum[i]-s[i] and Sum[i] + s[i]

But I, J can not be the same, so in the segment tree to maintain a second large value can be

When you delete the edges, modify the sum array to modify the segment tree.

#include <cstdio> #include <algorithm> #include <cstring> #include <iostream> #include <
queue> #define SF scanf #define PF printf #define LS (i<<1) #define RS (i<<1|1) using namespace std;
typedef long Long LL;
    inline 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 * + ch-' 0 '; ch = GetChar ();}
return x * F;
} const int MAXN = 100000; struct Node {int v, WT, next;}
EDGE[MAXN*2+10];
int adj[maxn+10], ecnt;
    void Addedge (int u, int v, int wt) {Node &e = edge[++ecnt]; E.V = v; e.wt = WT; E.next = Adj[u];
Adj[u] = ecnt;
} bool Iscir[maxn+10];
LL sum[maxn+10], dis[maxn+10], d[maxn+10], ld[maxn+10], rd[maxn+10], tot, ans, MX;
int cc, CIR[MAXN+10], fa[maxn+10], vis[maxn+10], N, p;
    struct Seg_tree {LL mx1[maxn*4+10], mx2[maxn*4+10];
    int p1[maxn*4+10], p2[maxn*4+10]; void Up (inT i) {if (Mx1[ls] > Mx1[rs]) {mx1[i] = Mx1[ls];
            P1[i] = P1[ls];
            Mx2[i] = Mx1[rs];
        P2[i] = P1[rs];
            } else {Mx1[i] = Mx1[rs];
            P1[i] = P1[rs];
            Mx2[i] = Mx1[ls];
        P2[i] = P1[ls];
            } if (Mx2[ls] > Mx2[i]) {mx2[i] = Mx2[ls];
        P2[i] = P2[ls];
            } if (Mx2[rs] > Mx2[i]) {mx2[i] = Mx2[rs];
        P2[i] = P2[rs];
            }} void build (int i, int l, int r) {if (L = = r) {Mx1[i] = Sum[l] + dis[l]; p1[i] = l;
            Mx2[i] = P2[i] = 0;
        return;
        } int mid = L+r >> 1;
        Build (LS, l, mid);
        Build (RS, mid+1, R);
    Up (i);
            } void ins (int i, int x, LL v, int L = 1, int R = cc) {if (L = = R) {Mx1[i] = V;
        return;
        } int mid = L+r >> 1; if (x <= mid) ins (LS, X, V, L, mid);
        else ins (rs, X, V, mid+1, R);
    Up (i);
}} T;
    struct Seg_tree2 {LL mx1[maxn*4+10], mx2[maxn*4+10];
    int p1[maxn*4+10], p2[maxn*4+10];
            void up (int i) {if (Mx1[ls] > Mx1[rs]) {mx1[i] = Mx1[ls];
            P1[i] = P1[ls];
            Mx2[i] = Mx1[rs];
        P2[i] = P1[rs];
            } else {Mx1[i] = Mx1[rs];
            P1[i] = P1[rs];
            Mx2[i] = Mx1[ls];
        P2[i] = P1[ls];
            } if (Mx2[ls] > Mx2[i]) {mx2[i] = Mx2[ls];
        P2[i] = P2[ls];
            } if (Mx2[rs] > Mx2[i]) {mx2[i] = Mx2[rs];
        P2[i] = P2[rs];
        }} void build (int i, int l, int r) {Mx1[i] = mx2[i] = -10000000000000000LL;
            if (L = = r) {Mx1[i] = Dis[l]-sum[l]; p1[i] = l;
        return;
        } int mid = L+r >> 1;
        Build (LS, l, mid);
        Build (RS, mid+1, R); Up (i);
    } void ins (int i, int x, LL v, int L = 1, int R = cc) {if (L = = R) {Mx1[i] = V;
        return;
        } int mid = L+r >> 1;
        if (x <= mid) ins (LS, x, V, L, mid);
        else ins (rs, X, V, mid+1, R);
    Up (i);
}} Q;
    bool Dfs (int u, int pre) {fa[u] = pre;
    Vis[u] = 1;
        for (int i = adj[u]; i; i = edge[i].next) {int v = EDGE[I].V;
        if (v = = pre) continue;
            if (Vis[v]) {cir[1] = V;
            FA[V] = u;
        return true;
    } if (Dfs (v, u)) return true;
} return false;
    } void Find_circle () {DFS (1, 0);
    int u = cir[1];
        while (Fa[u]! = cir[1]) {CIR[++CC] = Fa[u];
    U = fa[u];
        } for (int i = 1; I <= cc; i++) {Iscir[cir[i]] = true;
            for (int j = Adj[cir[i]]; j; j = edge[j].next) {int v = edge[j].v, wt = EDGE[J].WT;
if (v = = cir[i%cc+1]) {ld[i] = rd[i%cc+1] = WT;                tot + = WT;
            Break
}}} for (int i = 2; I <= cc; i++) sum[i] = Sum[i-1] + rd[i];
        } void DFS (int u, int pre) {for (int i = adj[u]; i; i = edge[i].next) {int v = edge[i].v, wt = EDGE[I].WT;
        if (v = = Pre | | iscir[v]) continue;
        D[V] = d[u] + wt;
        if (D[v] > d[p]) p = v;
    DFS (V, u);
    }} void Find_dis (int x) {int tmp;
    D[CIR[X]] = p = 0;
    DFS (Cir[x], 0);
    TMP = P;
    DIS[X] = d[p];
    Iscir[cir[x]] = false;
    D[TMP] = p = 0;
    DFS (tmp, 0);
    ans = max (ans, d[p]);
ISCIR[CIR[X]] = true;
    } int main () {n = read ();
        for (int i = 1; I <= n; i++) {int u, v, wt; U = Read (); v = read ();
        wt = read (); Addedge (U, v, wt);
    Addedge (V, u, wt);
    } find_circle ();
    for (int i = 1; I <= cc; i++) Find_dis (i);
    T.build (1, 1, CC);
    Q.build (1, 1, CC);
    LL ANS = 10000000000000000LL; for (int i = 1; I <= cc; i++){if (t.p1[1]! = q.p1[1]) ANS = min (ans, t.mx1[1] + q.mx1[1]);
        else ANS = min (ans, max (t.mx1[1]+q.mx2[1], t.mx2[1]+q.mx1[1])); Sum[i] = Rd[i] + sum[(i>1)?
        (i-1): CC];
        T.ins (1, I, Dis[i]+sum[i], 1, CC);
    Q.ins (1, I, Dis[i]-sum[i], 1, CC);
} PF ("%.1lf\n", (double) max (ans, ans)/(double) 2.0); }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.