Cod sursa(job #2673435)

Utilizator PopescuAndreiAlexandruPopescu Andrei Alexandru PopescuAndreiAlexandru Data 16 noiembrie 2020 19:45:45
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.44 kb
#include <bits/stdc++.h>

using namespace std;

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

const int DIM = 15005;

int n,m,k,C[DIM],M[DIM],B[DIM],D[DIM];

int WhatChain[DIM],PosInChain[DIM],Chains[DIM],nrChains,Parent[DIM],Cost[DIM],Head[DIM],a,b,P[DIM];

int t[DIM],rg[DIM],Tree[DIM*4+5],ans;

bitset <DIM> seen;

vector < pair<int,int> > G[DIM];

struct Graph
{
    int x,y,c;
}T[DIM*2];

bool Compare(Graph a, Graph b)
{
    return(a.c<b.c);
}

int Find(int nod)
{
    while(nod!=t[nod])
        nod=t[nod];
    return nod;
}


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

void Read()
{
    fin>>n>>m>>k;
    for(int i=1;i<=m;i++)
            fin>>T[i].x>>T[i].y>>T[i].c;
    for(int i=1;i<=n;i++)
        {
            rg[i]=1;
            t[i]=i;
        }
    sort(T+1,T+1+m,Compare);
}

void GetGraph()
{
    for(int i=1;i<=m;i++)
        {
            int a=T[i].x;
            int b=T[i].y;
            if(Find(a)!=Find(b))
                {
                    G[a].push_back(make_pair(b,T[i].c));
                    G[b].push_back(make_pair(a,T[i].c));
                    Union(Find(a),Find(b));
                }
        }
}

void DFS(int nod)
{
    C[nod]=1;
    vector < pair<int,int> > ::iterator it;
    for(it=G[nod].begin();it!=G[nod].end();it++)
        {
            int next=(*it).first;
            int edge=(*it).second;
            if(!C[next])
                {
                    D[next]=D[nod]+1;
                    Cost[next]=edge;
                    DFS(next);
                    C[nod]+=C[next];
                    if(C[next]>M[nod])
                        {
                            M[nod]=C[next];
                            B[nod]=next;
                        }
                }
        }
}

void GetChains(int nod)
{
    seen[nod]=1;
    vector < pair<int,int> > ::iterator it;
    for(it=G[nod].begin();it!=G[nod].end();it++)
        {
            if(!seen[(*it).first])
                GetChains((*it).first);
        }
    if(C[nod]==1)
        {
            nrChains++;
            WhatChain[nod]=nrChains;
            PosInChain[nod]=1;
        }
    else
        {
            WhatChain[nod]=WhatChain[B[nod]];
            PosInChain[nod]=PosInChain[B[nod]]+1;
            for(unsigned i=0;i<G[nod].size();i++)
                {
                    int r = G[nod][i].first;
                    if(r!=B[nod])
                        Parent[WhatChain[r]]=nod;
                }
        }
    Chains[WhatChain[nod]]++;
    Head[WhatChain[nod]]=nod;
}

void UpdateTree(int nod, int st, int dr, int pos, int val)
{
    if(st==dr)
        {
            Tree[nod]=val;
            return;
        }
    int mij=(st+dr)>>1;
    if(pos<=mij)
        UpdateTree(2*nod,st,mij,pos,val);
    else
        UpdateTree(2*nod+1,mij+1,dr,pos,val);
    Tree[nod]=max(Tree[2*nod],Tree[2*nod+1]);
}

void QueryTree(int nod, int st, int dr, int a, int b)
{
    if(st>=a && dr<=b)
        {
            ans=max(ans,Tree[nod]);
            return;
        }
    int mij=(st+dr)>>1;
    if(a<=mij)
        QueryTree(2*nod,st,mij,a,b);
    if(b>mij)
        QueryTree(2*nod+1,mij+1,dr,a,b);
}

void UpdateChains()
{
    for(int i=1;i<=nrChains;i++)
            P[i]=P[i-1]+Chains[i];
    for(int i=1;i<=n;i++)
            UpdateTree(1,1,n,P[WhatChain[i]-1]+PosInChain[i],Cost[i]);
}

void Query()
{
    while(k--)
        {
            fin>>a>>b;
            ans=0;
            while(WhatChain[a]!=WhatChain[b])
                {
                    int p1=Head[WhatChain[a]];
                    int p2=Head[WhatChain[b]];
                    if(D[p1]<=D[p2])
                        swap(a,b);
                    int l = P[WhatChain[a]-1] + PosInChain[a], r = P[WhatChain[a]];
                    QueryTree(1,1,n,l,r);
                    a = Parent[WhatChain[a]];
                }
            if(PosInChain[a]>PosInChain[b])
                swap(a,b);
            int l = P[WhatChain[a]-1] + PosInChain[a], r = P[WhatChain[b]-1] + PosInChain[b] - 1;
            if(l<=r)
                QueryTree(1,1,n,l,r);
            fout<<ans<<'\n';
        }
}

int main()
{
    Read();
    GetGraph();
    DFS(1);
    GetChains(1);
    UpdateChains();
    Query();
}