Cod sursa(job #2479274)

Utilizator andreiomd1Onut Andrei andreiomd1 Data 23 octombrie 2019 17:26:00
Problema PScNv Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.13 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

typedef pair < int, int > PII;
typedef pair < int, pair < int, int > > PIII;

const int BSIZE = (1 << 16), NMAX = 25e4 + 5;

int N, M, X, Y, Max;

vector < PII > G[NMAX];
vector < PIII > Edges;

bool Sel[NMAX];

int pos = BSIZE - 1;
char buff[BSIZE];

int T[NMAX], Ap[NMAX];

static inline void Initialize (int N)
{
    for(int i = 1; i <= N; ++i)
        T[i] = i, Ap[i] = 1;

    return;
}

static inline int Find (int Node)
{
    if(Node == T[Node])
        return Node;

    return T[Node] = Find(T[Node]);
}

static inline bool Unify (int X, int Y)
{
    X = Find(X);
    Y = Find(Y);

    if(X == Y)
        return false;

    if(Ap[X] > Ap[Y])
    {
        Ap[X] += Ap[Y];
        Ap[Y] = 0;

        T[Y] = X;

        return true;
    }

    Ap[Y] += Ap[X];
    Ap[X] = 0;

    T[X] = Y;

    return true;
}

static inline char C ()
{
    ++pos;

    if(pos == BSIZE)
    {
        pos = 0;

        fread(buff, 1, BSIZE, stdin);
    }

    return buff[pos];
}

static inline int I ()
{
    int r = 0;

    for(;;)
    {
        int Ch = C();

        if(isdigit(Ch))
        {
            r = (Ch - '0');

            break;
        }
    }

    for(;;)
    {
        char Ch = C();

        if(isdigit(Ch))
            r = r * 10 + (Ch - '0');
        else break;
    }

    return r;
}

static inline void Read ()
{
    ios_base :: sync_with_stdio(false);
    cin.tie(NULL);

    freopen("pscnv.in", "r", stdin);
    freopen("pscnv.out", "w", stdout);

    N = I();
    M = I();
    X = I();
    Y = I();

    for(int i = 1; i <= M; ++i)
    {
        int nx = I(), ny = I(), k = I();

        G[nx].push_back({k, ny});

        Max = max(Max, k);
    }

    return;
}

static inline void Go (int Node, int W)
{
    Sel[Node] = true;

    for(auto it : G[Node])
        if(!Sel[it.second] && it.first <= W)
            Go(it.second, W);

    return;
}

static inline bool Ok (int W)
{
    for(int i = 1; i <= N; ++i)
        Sel[i] = false;

    Go(X, W);

    return Sel[Y];
}

static inline void Task1 ()
{
    int Left = 1, Right = Max, ans = 0;

    while(Left <= Right)
    {
        int Mid = (Left + Right) / 2;

        if(Ok(Mid))
        {
            ans = Mid;

            Right = Mid - 1;
        }
        else Left = Mid + 1;
    }

    printf("%d\n", ans);

    return;
}

static inline void Load ()
{
    for(int i = 1; i <= N; ++i)
        for(auto it : G[i])
            Edges.push_back({it.first, {i, it.second}});

    return;
}

static inline void Task2 ()
{
    Initialize(N);

    Load();

    int ans = 0;

    sort(Edges.begin(), Edges.end());

    for(auto it : Edges)
        if(Unify(it.second.first, it.second.second))
            if(Find(it.second.first) == Find(X))
                ans = max(ans, it.first);

    printf("%d\n", ans);

    return;
}

int main()
{
    Read();

    if(N <= 1e5)
        Task1();
    else Task2();

    return 0;
}