Cod sursa(job #2227459)

Utilizator tifui.alexandruTifui Ioan Alexandru tifui.alexandru Data 31 iulie 2018 20:15:45
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.49 kb
#include <bits/stdc++.h>
#define Nmax 15005
#define Mmax 30005
#define DIM 70000
using namespace std;

class Ifstream
{
private:
    FILE *f;
    char *buffer;
    int cursor;
    char read_ch()
    {
        if(++cursor==DIM)
        {
            cursor=0;
            fread(buffer,1,DIM,f);
        }
        return buffer[cursor];
    }

public:
    Ifstream(const char *file_name)
    {
        f=fopen(file_name,"r");
        buffer=new char[DIM]();
        cursor=DIM-1;
    }

    Ifstream &operator >> (int &n)
    {
        char c;
        n=0;
        while(!isdigit(c=read_ch()) and c!='-');

        int sgn=1;
        if(c=='-') sgn=-1;
        else n=c-'0';

        while(isdigit(c=read_ch()))
            n=10*n+c-'0';
        n*=sgn;

        return *this;
    }

};

class Ofstream
{
private:
    FILE *g;
    char *buffer;
    int cursor;
    void write_ch(char ch)
    {
        if(cursor==DIM)
        {
            fwrite(buffer,1,DIM,g);
            cursor=0;
        }
        buffer[cursor++]=ch;
    }

public:
    Ofstream(const char *file_name)
    {
        g=fopen(file_name,"w");
        buffer=new char[DIM]();
        cursor=0;
    }

    ~Ofstream()
    {
        fwrite(buffer,1,cursor,g);
        fclose(g);
    }

    Ofstream &operator << (int n)
    {
        if(n<10) write_ch(n+'0');
        else
        {
            (*this)<<(n/10);
            write_ch(n%10+'0');
        }
        return *this;
    }

    Ofstream &operator << (char c)
    {
        write_ch(c);
        return *this;
    }

};

Ifstream f("radiatie.in");
Ofstream g("radiatie.out");

struct edge
{
    int l,r,val;
    bool operator < (const edge &other) const
    {
        return this->val<other.val;
    }
};

edge E[Mmax];
int t[Nmax],r[Nmax],v[Nmax],lvl[Nmax],Log2[Nmax<<1],poz[Nmax];
int rmq[20][Nmax<<1],M[20][Nmax],T[20][Nmax];
int n,m,Q,N;
list < pair <int,int> > tree[Nmax];

int Find(int x)
{
    int root=x;
    while(root!=t[root])
        root=t[root];
    int aux;
    while(x!=t[x])
    {
        aux=t[x];
        t[x]=root;
        x=aux;
    }
    return root;
}

void Unite(int x, int y)
{
    if(r[x]<r[y]) t[x]=y;
    else t[y]=x;
    if(r[x]==r[y]) r[x]++;
}

void Kruskal()
{
    sort(E+1,E+m+1);
    int i,x,y,nr;
    for(i=1;i<=n;i++)
    {
        t[i]=i;
        r[i]=1;
    }
    i=1;
    nr=0;
    while(nr<n-1)
    {
        x=Find(E[i].l);
        y=Find(E[i].r);
        if(x!=y)
        {
            Unite(x,y);
            tree[E[i].l].push_back({E[i].r,E[i].val});
            tree[E[i].r].push_back({E[i].l,E[i].val});
            ++nr;
        }
        ++i;
    }
}

void DFS(int x)
{
    rmq[0][++N]=x;
    poz[x]=N;
    for(const auto &it:tree[x])
        if(!lvl[it.first])
        {
            lvl[it.first]=lvl[x]+1;
            T[0][it.first]=x;
            M[0][it.first]=it.second;
            DFS(it.first);
            rmq[0][++N]=x;
        }
}

inline int min_criterion(const int &x,const int &y)
{
    if(lvl[x]<lvl[y]) return x;
    return y;
}

void Compute_rmq()
{
    int i,j;

    Log2[2]=1;
    for(i=3;i<=N;i++)
        Log2[i]=Log2[i>>1]+1;

    for(i=1;i<=Log2[N];i++)
        for(j=1;j+(1<<(i-1))<=N;j++)
            rmq[i][j]=min_criterion(rmq[i-1][j],rmq[i-1][j+(1<<(i-1))]);
}

void Compute_ancestors()
{
    int i,j;
    bool ok=true;
    for(i=1;ok;i++)
    {
        ok=false;
        for(j=1;j<=n;j++)
        {
            T[i][j]=T[i-1][T[i-1][j]];
            M[i][j]=max(M[i-1][j],M[i-1][T[i-1][j]]);
            if(T[i][j]) ok=true;
        }
    }
}

int LCA(int x, int y)
{
    x=poz[x];
    y=poz[y];
    if(x>y) swap(x,y);
    int k=Log2[y-x+1];
    return min_criterion(rmq[k][x],rmq[k][y-(1<<k)+1]);
}

int get_max_val(int node, int lca)
{
    int diff=lvl[node]-lvl[lca];
    int ans=0;
    while(diff)
    {
        ans=max(ans,M[Log2[diff]][node]);
        node=T[Log2[diff]][node];
        diff-=(1<<Log2[diff]);
    }
    return ans;
}

int main()
{
    f>>n>>m>>Q;
    int x,y,k,val1,val2,cnt;
    for(cnt=1;cnt<=m;cnt++)
        f>>E[cnt].l>>E[cnt].r>>E[cnt].val;
    Kruskal();

    lvl[1]=1;
    DFS(1);

    Compute_rmq();
    Compute_ancestors();

    while(Q--)
    {
        f>>x>>y;
        k=LCA(x,y);
        val1=get_max_val(x,k);
        val2=get_max_val(y,k);
        g<<max(val1,val2)<<'\n';
    }

    return 0;
}