Cod sursa(job #1542155)

Utilizator pepsiM4A1Ozturk Arif pepsiM4A1 Data 5 decembrie 2015 01:30:08
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.23 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#define MUCMAX 30023
#define NMAX 15023
#define INFINIT 100023
#define LG 31
using namespace std;
int n,m,p;
struct str
{
    int n1;
    int n2;
    int cost;
}s[MUCMAX];
int rmq1[INFINIT][17],aparitie[NMAX],stram[NMAX][LG],muchie[NMAX][LG];
vector<int>adjt[NMAX],costt[NMAX],adj[NMAX],cost[NMAX],ap[NMAX];
int ps,parc[INFINIT],niv[INFINIT],c[INFINIT],t[NMAX],marime[NMAX],setm[MUCMAX],lunset,nniv[NMAX];
bool vis[NMAX];
int log2(int a)
{
    for(int i=31;i>=0;i--)
    {
        if(a&(1<<i)) return i;
    }
    return 0;
}
int comp(const str &a,const str &b)
{
    return a.cost<b.cost;
}
int tata(int nod)
{
    if(t[nod]!=0)
    {
        t[nod]=tata(t[nod]);
        return t[nod];
    }
    return nod;
}
void kruskal()
{
    for(int i=1;i<=n;i++) marime[i]=1;
    for(int i=1;i<=m;i++)
    {
        int t1=tata(s[i].n1),t2=tata(s[i].n2);
        if(t1==t2) continue;
        if(marime[t1]<=marime[t2])
        {
            t[t2]=t1;
            marime[t1]=max(marime[t1],marime[t2]+1);
        }
        else
        {
            t[t1]=t2;
            marime[t2]=max(marime[t2],marime[t1]+1);
        }
        setm[++lunset]=i;
    }
}
void dfs(int nod)
{
    vis[nod]=1;
    vector<int>::iterator it1,it2;
    for(it1=adjt[nod].begin(),it2=costt[nod].begin();it1!=adjt[nod].end();++it1,++it2)
    {
        if(vis[*it1]==0)
        {
            adj[nod].push_back(*it1);
            cost[nod].push_back(*it2);
            dfs(*it1);
        }
    }
}
void df(int nod,int nivel)
{
    parc[++ps]=nod;
    niv[ps]=nivel;
    nniv[nod]=nivel;
    vector<int>::iterator it1,it2;
    for(it1=adj[nod].begin(),it2=cost[nod].begin();it1!=adj[nod].end();++it1,++it2)
    {
        df(*it1,nivel+1);
        parc[++ps]=nod;
        niv[ps]=nivel;
    }
}
inline void creatermq1()
{
    int lg=log2(ps);
    for(int i=1;i<=ps;i++) rmq1[i][0]=i;
    for(int j=1;j<=lg;j++)
    {
        for(int i=1;i+(1<<j)<=ps;i++)
        {
            if(niv[rmq1[i][j-1]]<niv[rmq1[i+(1<<(j-1))][j-1]]) rmq1[i][j]=rmq1[i][j-1];
            else rmq1[i][j]=rmq1[i+(1<<(j-1))][j-1];
        }
    }
}
int query1(int p1,int p2)
{
    if(p1>p2) swap(p1,p2);
    int lg=log2(p2-p1+1);
    if(niv[rmq1[p1][lg]]<=niv[rmq1[p2-(1<<lg)+1][lg]]) return parc[rmq1[p1][lg]];
    return parc[rmq1[p2-(1<<lg)+1][lg]];
}
int querystram(int n1,int n2)
{
    int cat=nniv[n2]-nniv[n1];
    int maxim=0,sum=0;
  //  printf("%d ",n2);
    for(int i=0;i<=30;i++)
    {
        if(cat&(1<<i))
        {
            if(maxim<muchie[n2][i]) maxim=muchie[n2][i];
            n2=stram[n2][i];
            sum+=(1<<i);
          //  printf("%d ",n2);
        }
    }
    if(sum!=cat) while(1);
    return maxim;
}
int main()
{
    freopen ("radiatie.in","r",stdin);
    freopen ("radiatie.out","w",stdout);
    scanf("%d%d%d",&n,&m,&p);
    for(int i=1;i<=m;i++) scanf("%d%d%d",&s[i].n1,&s[i].n2,&s[i].cost);
    sort(s+1,s+m+1,comp);
    kruskal();
    for(int i=1;i<=lunset;i++)
    {
        adjt[s[setm[i]].n1].push_back(s[setm[i]].n2);
        adjt[s[setm[i]].n2].push_back(s[setm[i]].n1);
        costt[s[setm[i]].n1].push_back(s[setm[i]].cost);
        costt[s[setm[i]].n2].push_back(s[setm[i]].cost);
    }
    dfs(1);
    df(1,1);
    for(int i=1;i<=ps;i++) if(aparitie[parc[i]]==0) aparitie[parc[i]]=i;
    creatermq1();
    int nr1,nr2;
    for(int i=1;i<=n;i++)
    {
        vector<int>::iterator it1,it2;
        for(it1=adj[i].begin(),it2=cost[i].begin();it1!=adj[i].end();++it1,++it2)
        {
            stram[*it1][0]=i;
            muchie[*it1][0]=*it2;
        }
    }
    for(int i=2;i<=n;i++) if(stram[i][0]==0) while(1);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<LG;j++) stram[i][j]=stram[stram[i][j-1]][j-1];
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<LG;j++) muchie[i][j]=max(muchie[i][j-1],muchie[stram[i][j-1]][j-1]);
    }
    int nod1,nod2,t1,t2;
    for(int i=1;i<=p;i++)
    {
        scanf("%d%d",&nod1,&nod2);
        t1=aparitie[nod1];
        t2=aparitie[nod2];
        int fin=query1(t1,t2);
        printf("%d\n",max(querystram(fin,nod1),querystram(fin,nod2)));
    }
}