Luo Gu solution to a problem UVA11354 [Bond] bottleneck tree + kruskal + minimum common ancestor

Similar problem is with 2245.
Main use of the minimum spanning tree seeking maximum value because the minimum spanning tree is small to large sort.
Chris Carr of the sort used in the algorithm.

LCA algorithm derived by a recent common ancestor, and then in seeking common ancestor of the road, has been taking the maximum value. Successfully got the minimum spanning tree maximum

// prim not tried. It should be


`` `
#include <bits / STDC ++ H.>
The using namespace STD;
const int N = 1e6;
#define INF 0x3f3f3f3f;
int depth [N], n-, m, CNT, FA [N] [30], Fi [N], BA [N], W [N] [30], Q, MST;
BOOL ISV [N]; // ISV access cnt try to explain the depth of depth. .

// fa ba doubled save ancestors seeking father (dad) w maximum deposit edge weights are mst MST algorithm. .

of Mo struct
{
    int from, to, W;
    BOOL operator <(A of Mo) const {return W <AW;} // get overloaded minimum spanning tree
} e [N]; // save sides


struct Li
{
    int to, W , NXT;
} EG [N]; // for connecting


inline int Find (int X Register)
{
    BA return [X] = (BA [X] X X ==:? Find (BA [X]));
} // find the path of compressed father


inline void add (register int x, register int y, register int w)
{
    EG [CNT ++] = Y .to, EG [CNT] .W = W, EG [CNT] .nxt = Fi [X];
    Fi [X] = CNT;
} // chain before addition of the star


Read int inline ()
{
    Register R & lt int = 0, F =. 1;
    Register char E = getchar ();
    the while (isdigit (E)!)
    {
        IF (E == '-')
        F = -1;
        E = getchar ();
    }
    the while (isdigit (E))
    R & lt = (R & lt <<. 1) + (R & lt <<. 3) - '0' + E, E = getchar ();
    return F * R & lt;
} // fast read, this is useful


inline void OUT (int X Register)
{
    IF (X>. 9)
    OUT (X / 10);
    the putchar (X + 10% '0');
} // lose fast, in fact, nothing efficient


inline void the init ()
{
    Memset (Fi, 0, the sizeof (Fi));
    CNT = 0, MST = 0;
    Memset (ISV, 0, the sizeof (ISV));
} // initialize


inline void Kruskal ()
{
    Sort (. 1 E +, E +. 1 + m); // call to sort
    for (int I = Register. 1; I <= m; I ++)
    {
        Register int X = Find (E [ I] .from), Y = Find (E [I] .to);
        ! IF (X = Y)
        {
            BA [X] = Y;
            the Add (E [I] .from, E [I] .to, E [I] .W);
            the Add (E [I] .to, E [I] .from, E [I] .W); // bidirectional link with a forward star.
            ++ MST;
            IF (MST-n-==. 1) BREAK; // if this limitation is also possible without ever
        }
    }
} // minimum spanning tree


inline void DFS (int X)
{
    ISV [X] = to true;
    for (int I = Fi Register [X]; I; I EG = [I] .nxt)
    {
        Register int to EG = [I] .to;
        IF (ISV [to]) Continue; // continue to be accessed
        depth [to] = depth [x ] +1; // add depth otherwise. 1
        FA [to] [0] = X; // save the father
        w [to] [0] = eg [i] .w; // save father weight
        DFS (to);
    }
    return;
} // search depth calculation, initialized FA, W


inline int the LCA (X Register int, int Y Register)
{
    IF return - (Find (X) = Find (Y)!) . 1;
    Register ANS int = 0;
    IF (depth [X] <depth [Y]) the swap (X, Y);
    for (int I = Register 25; I> = 0; I -) // 25 can also be used Iog2 (K) K = n-
        IF (depth [FA [X] [I]]> = depth [Y]) ANS = max (ANS, W [X] [I]), X = FA [X] [I] ; // ans and x can not reverse the order, first taking the maximum update, the maximum priority value is stored
    if (x == y) return ans ;
    for (int I = Register 25; I> = 0; i--)
        IF (! FA [X] [I] FA = [Y] [I])
        ANS = max (ANS, max (W [X] [I ], W [Y] [I])), X = FA [X] [I], Y = FA [Y] [I];
    ANS = max (ANS, max (W [X] [0], W [ y] [0])); // supra
    return ANS;
} // find the common ancestor


int main ()
{
    int In Flag = 0;
    the while (Scanf ( "% D% D", & n-, & m) == 2)
    {
        IF (in Flag = 0!) the putchar (10);
        the else
        {
            in Flag =. 1;
        } // this is the very point of the pit is a pit. Hang a day. The last set of data does not straddle a row
    for (int I = Register. 1; I <= m; I ++)
    E [I] .from = Read (), E [I] .to = Read (), E [I]. W = Read ();
    for (Register int I =. 1; I <= n-; I ++)
    BA [I] = I;
    Kruskal ();
    for (Register int I =. 1; I <= n-; I ++)
    {
        if(!isv[i])
        {
            depth[i]=1;
            dfs(i);
            fa[i][0]=i;
            w[i][0]=-1;//初始化
        }
    }
    for(register int i=1;i<=25;i++)
        for(register int j=1;j<=n;j++)
        {
            fa[j][i]=fa[fa[j][i-1]][i-1];
            w[j][i]=max(w[j][i-1],w[fa[j][i-1]][i-1]);
        }//倍增求最大值
    q=read();
    for(register int i=1;i<=q;i++)
    {
        register int x=read(),y=read();
        int z=LCA(x,y);
        printf("%d",z);
        putchar(10);
    }
    init();多组数据所以再初始化
}
    return 0;
}
`` `
(~ ~ ~ ~ Konjac) first wrote solution to a problem, a lot of support on the right, by the way Amway wave of new blog https://www.cnblogs.com/sscdg/;

Guess you like

Origin www.cnblogs.com/sscdg/p/11412592.html