Cod sursa(job #568381)

Utilizator ChallengeMurtaza Alexandru Challenge Data 31 martie 2011 09:46:57
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

const char InFile[]="radiatie.in";
const char OutFile[]="radiatie.out";
const int MaxM=1<<15;
const int MaxN=1<<14;
const int LogMaxN=16;

ifstream fin(InFile);
ofstream fout(OutFile);

struct s_edge
{
	s_edge(int _x=0, int _y=0, int _c=0):x(_x),y(_y),c(_c){}
    int x,y,c;
};

struct s_edge2
{
	s_edge2(int _y=0, int _c=0):y(_y),c(_c){}
    int y,c;
};

struct cmp
{
    inline bool operator() (const s_edge &a, const s_edge &b)
    {
        return a.c<b.c;
    }
};

int N,M,K,x,y,k,pmd[MaxN],niv[MaxN],T[LogMaxN][MaxN],C[LogMaxN][MaxN],viz[MaxN],lg[MaxN];
s_edge E[MaxM];
vector<s_edge2> G[MaxN];

inline void init_pmd()
{
    for(register int i=1;i<=N;++i)
    {
        pmd[i]=-1;
    }
}

inline int find(int nod)
{
    int sol=nod;
    while(pmd[sol]>0)
    {
        sol=pmd[sol];
    }
    int x=sol;
    while(x!=sol)
    {
        int t=pmd[x];
        pmd[x]=sol;
        x=t;
    }
    return sol;
}

inline void unify(int x,int y)
{
    int rx=find(x);
    int ry=find(y);
	if(rx!=ry)
	{
		if(pmd[rx]<pmd[ry])
		{
			pmd[rx]+=pmd[ry];
			pmd[ry]=rx;
		}
		else
		{
			pmd[ry]+=pmd[rx];
			pmd[rx]=ry;
		}
	}
}

inline bool unified(int x, int y)
{
    return find(x)==find(y);
}

inline void kruskal()
{
    sort(E+1,E+1+M,cmp());
    init_pmd();
    for(register int i=1;i<=M;++i)
    {
        if(!unified(E[i].x,E[i].y))
        {
            unify(E[i].x,E[i].y);
			G[E[i].x].push_back(s_edge2(E[i].y,E[i].c));
			G[E[i].y].push_back(s_edge2(E[i].x,E[i].c));
        }
    }
}

void DFS(int nod,int t)
{
    if(viz[nod])
    {
        return;
    }
	viz[nod]=1;
	niv[nod]=k;
    ++k;
    T[0][nod]=t;
    for(vector<s_edge2>::iterator it=G[nod].begin();it!=G[nod].end();++it)
    {
        if(it->y!=t)
        {
            DFS(it->y,nod);
        }
        else
        {
            C[0][nod]=it->c;
        }
    }
    --k;
}

inline int query(int x,int y)
{
	int c=0;
    if(niv[x]<niv[y])
    {
        swap(x,y);
    }
    while(niv[x]!=niv[y])
    {
        int k=niv[x]-niv[y];
		c=max(c,C[lg[k]][x]);
        x=T[lg[k]][x];
    }
	int k=LogMaxN-1;
	while(x!=y)
	{
		while(T[k][x]==T[k][y] && k>-1)
		{
			--k;
		}
		if(k==-1)
		{
			c=max(c,C[0][x]);
			c=max(c,C[0][y]);
			break;
		}
		c=max(c,C[k][x]);
		c=max(c,C[k][y]);
		x=T[k][x];
		y=T[k][y];
	}
	return c;
}

inline void preprocesare()
{
    for(register int i=1;i<LogMaxN;++i)
    {
        for(register int j=1;j<=N;++j)
        {
			T[i][j]=T[i-1][T[i-1][j]];
            C[i][j]=max(C[i-1][j],C[i-1][T[i-1][j]]);
        }
    }
}

int main()
{
    fin>>N>>M>>K;
    for(register int i=1;i<=M;++i)
    {
        fin>>E[i].x>>E[i].y>>E[i].c;
    }
    kruskal();
    for(register int i=1;i<=N;++i)
    {
        if(!viz[i])
        {
            DFS(i,0);
        }
    }
	for(register int i=2;i<=N;++i)
	{
		lg[i]=lg[i>>1]+1;
	}
    preprocesare();
    for(register int i=1;i<=K;++i)
    {
        fin>>x>>y;
        fout<<query(x,y)<<"\n";
    }
    fin.close();
    fout.close();
    return 0;
}