Cod sursa(job #177817)

Utilizator vlad_popaVlad Popa vlad_popa Data 13 aprilie 2008 17:16:32
Problema Radiatie Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.94 kb
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;

#define ii pair <int, int>
#define MAXN 15005
#define x first
#define y second
#define mp make_pair
#define pb push_back

int N, M, K;
vector < pair <int, ii> > edge;
int r[MAXN], h[MAXN];
vector < ii > f[MAXN];
ii str[15][MAXN], p[MAXN];
int cd[MAXN];

void read ()
{
    int a, b, c;
    for (scanf (" %d %d %d", &N, &M, &K); M; -- M)
    {
        scanf (" %d %d %d", &a, &b, &c);
        edge.pb(mp(c, mp(a, b)));
    }
    sort (edge.begin(), edge.end());
}

inline int root (int n)
{
    if (n != r[n]) return r[n] = root (r[n]);
    return n;
}

inline void unite (int n1, int n2)
{
    if (h[n1] > h[n2]) r[n2] = n1;
    else r[n1] = n2;
    if (h[n2] == h[n1]) ++ h[n1];
}

void Kruskal ()
{
    int i, cnt = 1;
    for (i = 1; i <= N; ++ i) r[i] = i;
    
    for (i = 0; cnt < N; ++ i)
    {
        int r1 = root(edge[i].y.x), r2 = root(edge[i].y.y);
        if (r1 != r2)
        {
            f[edge[i].y.x].pb (mp (edge[i].y.y, edge[i].x)); 
            f[edge[i].y.y].pb (mp (edge[i].y.x, edge[i].x));
            unite(r1, r2); ++ cnt;
        }
    }
}

void APM (int s)
{
    int ended, pas, i, sz, nod;
    cd[ended = 0] = s; h[s] = 1;
    
    for (pas = 0; pas <= ended; ++ pas)
    {
        nod = cd[pas];
        for (i = 0, sz = f[nod].size(); i < sz; ++ i)
            if (!h[f[nod][i].x])
            {
                p[f[nod][i].x].x = nod;  p[f[nod][i].x].y = f[nod][i].y;
                h[f[nod][i].x] = h[nod] + 1;
                cd[++ ended] = f[nod][i].x;
            }
    }
}

int Min_Path (int a, int b)
{
    int i, Max = 0;
    if (h[a] < h[b]) swap (a, b);
    if (h[a] > h[b]) 
        for (i = 0; (1<<i) <= N; ++ i)
            if ((h[a] - h[b]) & (1 << i))
            {
                Max = max (str[i][a].y, Max);
                a = str[i][a].x;               
            }
            
    while (a != b)
    {
        for (i = 0; str[i][a].x != str[i][b].x; ++ i);
        
        int j = i ? i : 0;
        Max = max (Max, str[j][a].y); Max = max (Max, str[j][b].y); 
        a = str[j][a].x; b = str[j][b].x;
    }
    
    return Max;
}

void solve ()
{
    int i, j, a, b;
    Kruskal();
    
    memset (h, 0, sizeof(h));
    for (i = 1; i <= N; ++ i)
        if (r[i] == i) APM(i);
    
    for (i = 1; i <= N; ++ i) str[0][i] = p[i];
    
    for (i = 1; (1<<i) <= N; ++ i)
        for (j = 1; j <= N; ++ j)   
            str[i][j].x = str[i-1][str[i-1][j].x].x, str[i][j].y = max (str[i-1][j].y, str[i-1][str[i-1][j].x].y);
        
    for (i = 1; i <= K; ++ i)
    {
        scanf (" %d %d", &a, &b);
        printf ("%d\n", Min_Path(a, b));
    }
}

int
 main ()
{
    freopen ("radiatie.in", "rt", stdin);
    freopen ("radiatie.out", "wt", stdout);
    
    read ();
    solve ();
    
    return 0;
}