Cod sursa(job #94181)

Utilizator fireatmyselfBogdan-Alexandru Stoica fireatmyself Data 21 octombrie 2007 21:08:54
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.16 kb
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

#define NMAX 15051
#define TMAX (1<<16)
#define pb push_back
#define f first
#define s second
#define MAX(a,b) (((a)>(b))?(a):(b))

vector<int> A[NMAX], C[NMAX];
vector<pair<int,pair<int,int> > > V;

int N, M, K, F[NMAX], St[NMAX][22], Max[NMAX][22], Rep[NMAX];
int G[NMAX], tata[NMAX], cost[NMAX], E[3*NMAX], H[3*NMAX], Poz[NMAX];
int ne, P, Q, Min, Lca, Sol, T[2*TMAX];

int rep(int t)
{
        int x = t;

        while (Rep[x]!=x) x = Rep[x];
        
        return x;
}

void dfs(int i)
{
        int j, n = A[i].size(), fiu;

        if (i>1)
        {
                St[i][0] = tata[i]; Max[i][0] = cost[i];
                for (j = 1; j < 20; j++)
                {
                        fiu = St[i][j-1];
                        if (!fiu) break;
                        St[i][j] = St[fiu][j-1];
                        Max[i][j] = MAX(Max[i][j-1], Max[fiu][j-1]);
                }
        }

        F[i] = 1;
        if (i==10000)
           i = 10000;
        for (j = 0; j < n; j++)
            if (!F[ A[i][j] ])
            {
                tata[ A[i][j] ] = i;
                cost[ A[i][j] ] = C[i][j];
                dfs(A[i][j]);
            }
}

void euler(int i, int nv)
{
        int j, n = A[i].size();

        E[ne] = i;
        H[ne] = nv;
        Poz[i] = ne++;
        F[i] = 1;
        for (j = 0; j < n; j++)
            if (!F[A[i][j]])
            {
                euler(A[i][j],nv+1);
                E[ne] = i;
                H[ne] = nv;
                Poz[i] = ne++;
            }
}

void update(int x)
{
        int l, n = TMAX+x;

        while (n>1)
        {
                n = n>>1;
                l = n<<1;
                T[n] = T[l];
                if (H[T[l]]>H[T[l+1]]) T[n] = T[l+1];
                if (T[n]>ne)
                   l = 0;
        }
}

void lca(int p, int q, int n)
{
        int md = (p+q)>>1, l = n<<1;

        if (P <= p && q <= Q)
        {
                if (Min>H[T[n]]) Min = H[T[n]], Lca = E[T[n]];
                return;
        }

        if (p>q) return;

        if ( (p<=P&&P<=q)||(p<=Q&&Q<=q) )
        {
                lca(p,md,l);
                lca(md+1,q,l+1);
        }
}

int main()
{
        int i, j, k, m, x, y, t, fiu;

        freopen("radiatie.in", "r", stdin);
        scanf("%d%d%d", &N, &M, &K);

        for (i = 1; i <= N; i++) Rep[i] = i;

        for (m = 0; m < M; m++)
        {
                scanf("%d%d%d", &i, &j, &k);
                V.pb(make_pair(k,make_pair(i,j)));
        }

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

        for (m = 0; m < M; m++)
        {
                i = V[m].s.f; j = V[m].s.s; k = V[m].f;
                x = rep(i); y = rep(j);

                if (x!=y)
                {
                        Rep[y] = x;
                        A[i].pb(j); A[j].pb(i);
                        C[i].pb(k); C[j].pb(k);
                }
        }

        V.clear();
        dfs(1);

        for (i = 1; i <= N; i++) F[i] = 0;
        euler(1,1);
        for (i = 0; i < ne; i++) T[ TMAX+i ] = i;
        for (i = 0; i < ne; i++) update(i);

        freopen("radiatie.out", "w", stdout);
        for (k = 0; k < K; k++)
        {
                Sol = 0;
        
                scanf("%d%d", &i, &j);
                Min = 666000666; Lca = -1;
                P = Poz[i]; Q = Poz[j];
                if (P>Q) m = P, P = Q, Q = m;
                lca(0,TMAX-1,1);

                m = H[Poz[i]]-Min; fiu = i;
                for (t = 0; t < 20; t++)
                    if ( (m>>t)&1 )
                    {
                        Sol = MAX(Sol, Max[fiu][t]);
                        fiu = St[fiu][t];
                    }

                m = H[Poz[j]]-Min; fiu = j;
                for (t = 0; t < 20; t++)
                    if ( (m>>t)&1 )
                    {
                        Sol = MAX(Sol, Max[fiu][t]);
                        fiu = St[fiu][t];
                    }
                printf("%d\n", Sol);
        }

        return 0;
        
}