Cod sursa(job #1160625)

Utilizator andreiiiiPopa Andrei andreiiii Data 30 martie 2014 17:54:18
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.81 kb
#include <algorithm>
#include <fstream>
#include <cstdio>
#include <bitset>
#include <vector>

using namespace std;

const int BUFFER_SIZE=(1<<17);

class FileInput {
    public:
        FileInput() {}
        FileInput(const char *filename) {
            file = fopen(filename, "r");
            fread(buffer, BUFFER_SIZE, 1, file);
            cursor = 0;
        }
        inline FileInput & operator >> (int &n) {
            while(buffer[cursor] == ' ' || buffer[cursor] == '\n') {
                advance();
            }
            n = 0;
            while(isdigit(buffer[cursor])) {
                n = n * 10 + buffer[cursor] - '0';
                advance();
            }
            return *this;
        }
    private:
        FILE* file;
        char buffer[BUFFER_SIZE];
        int cursor;
        inline void advance() {
            ++ cursor;
            if(cursor == BUFFER_SIZE) {
                cursor = 0;
                fread(buffer, BUFFER_SIZE, 1, file);
            }
        }
};

FileInput fin("radiatie.in");
ofstream fout("radiatie.out");

const int N=15005, M=30005, LG=15;

struct mc
{
    int x, y, c;
    bool operator<(const mc &e) const
    {
        return c<e.x;
    }
} MC[M];

class Tree{
private:
    vector <vector<int>> G;
    vector <int> h, l, first, rmq[LG], cost[LG], lg, f[LG], lvln;
    int n, nr, ROOT;
    void dfs(const int n, const int lvl)
    {
        lvln[n]=lvl;
        h[++nr]=n;
        l[nr]=lvl;
        first[n]=nr;
        for(auto p: G[n])
        {
            dfs(p, lvl+1);
            h[++nr]=n;
            l[nr]=lvl;
        }
    }
    void build_rmq()
    {
        int i, j, y;
        for(i=2;i<=nr;i++) lg[i]=lg[i>>1]+1;
        for(i=1;i<=nr;i++) rmq[0][i]=i;
        for(i=1;(1<<i)<nr;i++)
        {
            y=1<<(i-1);
            for(j=1;j+(1<<i)<=nr;j++)
            {
                rmq[i][j]=rmq[i-1][j];
                if(l[rmq[i-1][j+y]]<l[rmq[i][j]])
                {
                    rmq[i][j]=rmq[i-1][j+y];
                }
            }
        }
    }
public:
    Tree(){n=nr=0;}
    Tree(const int _n)
    {
        n=_n;
        G.resize(n+5);
        first.resize(n+5);
        l.resize(2*n+5);
        lvln.resize(n+5);
        h.resize(2*n+5);
        lg.resize(2*n+5);
        for(int i=0;i<LG;i++) rmq[i].resize(2*n+5), f[i].resize(n+5), cost[i].resize(n+5);
    }
    void resize(const int _n)
    {
        n=_n;
        G.resize(n+5);
        first.resize(n+5);
        l.resize(2*n+5);
        lvln.resize(n+5);
        h.resize(2*n+5);
        lg.resize(2*n+5);
        for(int i=0;i<LG;i++) rmq[i].resize(2*n+5), f[i].resize(n+5), cost[i].resize(n+5);
    }
    void add_edge(const int x, const int y) {G[x].push_back(y);f[0][y]=x;}
    void set_cost(const int x, const int y) {cost[0][x]=y;}
    void set_root(const int x) {ROOT=x;}
    void build_ancestors()
    {
        dfs(ROOT, 0);
        build_rmq();
        for(int i=1;i<15;i++)
        {
            for(int j=1;j<=n;j++)
            {
                f[i][j]=f[i-1][f[i-1][j]];
                cost[i][j]=max(cost[i-1][j], cost[i-1][f[i-1][j]]);
            }
        }
    }
    int lca(int x, int y)
    {
        int diff, ret;
        x=first[x];
        y=first[y];
        if(x>y) swap(x, y);
        diff=lg[y-x+1];
        if(l[rmq[diff][x]]>l[rmq[diff][y-(1<<diff)+1]])
        {
            ret=rmq[diff][y-(1<<diff)+1];
        }
        else
        {
            ret=rmq[diff][x];
        }
        return h[ret];
    }
    int get_cost(int x, const int y)
    {
        int i, ret=0;
        for(i=14;i>=0;i--)
        {
            if((1<<i)&y)
            {
                ret=max(ret, cost[i][x]);
                x=f[i][x];
            }
        }
        return ret;
    }
    int get_path(const int x, const int y)
    {
        int c1, c2, nod;
        nod=lca(x, y);
        c1=get_cost(x, lvln[x]-lvln[nod]);
        c2=get_cost(y, lvln[y]-lvln[nod]);
        return max(c1, c2);
    }
};

Tree G;
int f[N];

int tfind(int x)
{
    int y, p;
    for(y=x;f[y]!=y;y=f[y]);
    for(;f[x]!=x;x=p)
    {
        p=f[x];
        f[x]=y;
    }
    return x;
}

int main()
{
    int n, m, q, i, x, y;
    fin>>n>>m>>q;
    G.resize(n);
    for(i=1;i<=m;i++) fin>>MC[i].x>>MC[i].y>>MC[i].c;
    sort(MC+1, MC+m+1);
    for(i=1;i<=n;i++) f[i]=i;
    for(i=1;i<=m;i++)
    {
        x=tfind(MC[i].x);
        y=tfind(MC[i].y);
        if(x!=y)
        {
            f[x]=y;
            G.add_edge(y, x);
            G.set_cost(x, MC[i].c);
        }
    }
    for(i=1;f[i]!=i;i++);
    G.set_root(i);
    G.build_ancestors();
    while(q--)
    {
        fin>>x>>y;
        fout<<G.get_path(x, y)<<"\n";
    }
}