Cod sursa(job #227682)

Utilizator toni2007Pripoae Teodor Anton toni2007 Data 5 decembrie 2008 10:40:33
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.92 kb
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <ctime>
#include <string>
#include <algorithm>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <bitset>
#include <map>
#include <stack>
#define pb push_back
#define mp make_pair
#define mt make_triple
#define For(i,a,b) for (i = a; i <= b; ++i)
#define oo (1<<30)
#define FIN "radiatie.in"
#define FOUT "radiatie.out"
#define N 15010
#define M 1000000
using namespace std;
struct triplet {	int first,second,third;  }; 
vector<triplet> Muchie;
triplet make_triple(int a,int b,int c){	triplet x;	x = (triplet) { a, b, c};	return x;}
inline bool cmp(triplet a,triplet b){	return a.third < b.third; }
int n,m,k;
int par[N];
vector<int> Cine[N],Cost[N];
int viz[N],t1[N],t2[N];
bool dif_comp(int x, int y) {
	int p1 = x, p2 = y;
	while (par[p1] != p1)
		p1 = par[p1];
	while (par[p2] != p2) 
		p2 = par[p2];
	
	if (p1 != p2) 	return true;
	else 			return false;
}

void merge_comp(int x, int y) {
	int p1 = x, p2 = y, ant, pp;
	while (par[p1] != p1) 
		p1 = par[p1];
	pp = p1;p1 = x;
	while (par[p1] != pp) {
		ant = p1;
		p1 = par[p1];
		par[ant] = pp;
	}
	while (par[p2] != pp) {
		ant = p2;
		p2 = par[p2];
		par[ant] = pp;
	}
}

void APM() {
	int i, ant, p, pp;
	for (i = 1; i <= n; ++i)
		par[i] = i;
	for (i = 0; i < m; ++i) {
		if (dif_comp(Muchie[i].first, Muchie[i].second)) {
			Cine[Muchie[i].first].push_back(Muchie[i].second);
			Cost[Muchie[i].first].push_back(Muchie[i].third);
			Cine[Muchie[i].second].push_back(Muchie[i].first);
			Cost[Muchie[i].second].push_back(Muchie[i].third);
			merge_comp(Muchie[i].first, Muchie[i].second);
		}
	}	
	for (i = 1; i <= n; ++i)
		if (par[i] == i) {
			Cine[i].push_back(0);
			Cine[0].push_back(i);
			Cost[0].push_back(0);
			Cost[i].push_back(0);
			par[i] = 0;
		}
}
int tata[N],nr;
int Euler[M],Lev[M],Level[N],pozi[N];
int arb[1000000],FFF = 0,last[N];
void df(int x,int level,int father,int Ultim){
	viz [x] = 1;
	Level[x] = level;
	Euler[ ++ nr] = x;
	Lev  [ nr] = level;
	tata[x] = father;
	t1 [x] = ++FFF;
	if (pozi[x] > nr)
		pozi[x] = nr;
	int i;
	last [x] = Ultim;
	for (i = 0; i < Cine[x].size(); ++i)
		if (!viz[Cine[x][i]]){
			df(Cine[x][i],level+1,x,Cost[x][i]);
			Euler[ ++ nr] = x;
			Lev  [ nr] = level;
		}
	t2 [x] = ++FFF;
}
int pos,val,start,finish;
void update(int nod,int l,int r){
    if (l==r){
        arb[nod]=val;
        return;
    }
    int mid=(l+r)>>1;
    if (pos<=mid) update(2*nod,l,mid);
    else          update(2*nod+1,mid+1,r);
    if (Lev[arb[2*nod]] > Lev[arb[2*nod+1]])
        arb[nod]=arb[2*nod+1];
    else
        arb[nod]=arb[2*nod];
}
int lca;
void query(int nod,int l,int r){
    if (start<=l && r<=finish){
        if (Lev[arb[nod]] < Lev[lca] || lca==0)
            lca=arb[nod];
        return;
    }
    int mid;
    mid=(l+r)>>1;
    if (start<=mid) query(2*nod,l,mid);
    if (mid<finish) query(2*nod+1,mid+1,r);
}
int str[N][18],best[N][18];
void RmqBuild(){  
    int i,j;  
    for (i = 0; i <= n; ++i){  
        str[i][0] = tata[i];  
        best[i][0] = last[i];  
    }  
    for (i = 1; i <= n; ++i)  
        for (j = 1; (1 << j) <= n; ++j)  
            best[i][j] = str[i][j] = oo;  
    for (i = 1; i <= n; ++i)  
        for (j = 1; (1 << j) <= n; ++j)  
            str[i][j] = str[str[i][j-1]][j-1];  
    for (i = 1; i <= n; ++i)  
        for (j = 1; (1 << j) <= n; ++j)  
            best[i][j]=max(best[i][j-1],best[str[i][j-1]][j-1]);   
}
void PreArbint(){  
	int nn = nr,i;  	
	for (i=1;i<=nn;++i){  
	    pos=i;  
        val=i;  
        update(1,1,nn);  
    }  
}
int rez_rmq;
void query_rmq(int x,int y){
    int p,q,f,j,now;
    p=Lev[x];
    q=Lev[y];
    f=p-q;now=x;
    //fprintf(stderr,"%d %d\n",x,y);
    while (f){
        for (j = 0; (1<<j) < f; ++j); if (j)--j;
        //fprintf(stderr,"%d %d %d %d\n",x,f,now,j);
        rez_rmq = max(rez_rmq,best[now][j]);
        now = str[now][j];
        p = Lev[now];
        f = p - q;
    }
}
int main(){
	int a,b,c,i,j,s1,s2,x,y,bla_now;
	freopen(FIN,"r",stdin);
	freopen(FOUT,"w",stdout);
	scanf("%d%d%d",&n,&m,&k);
	for (i = 1; i <= m; ++i){
		scanf("%d%d%d",&a,&b,&c);
		Muchie.pb(mt(a,b,c));
	}
	sort(Muchie.begin(), Muchie.end(), cmp);
	APM();
	for (i = 1; i <= n; ++i)
		pozi[i] = oo;
	df(0,0,0,0);
	PreArbint();
	RmqBuild();
	/*for (i = 1; i <= k; ++i){
		scanf("%d%d\n",&x,&y);
		if (t1[x]<t1[y] && t2[y]<t2[x])  
 	       lca=x;  
        else if(t1[y]<t1[x] && t2[x]<t2[y])  
           lca=y;
        else{
            lca=0;
            s1=pozi[x];
            s2=pozi[y];
            start=min(s1,s2);
            finish=max(s1,s2);
            query(1,1,nr);
            lca=Euler[lca];
        }
        //printf("%d\n",lca);
        if (x==y)
            bla_now=0;
        else{
            rez_rmq = 0;
            query_rmq(x,lca);
            bla_now = rez_rmq;
            rez_rmq = 0;
            query_rmq(y,lca);
            bla_now = max(bla_now,rez_rmq);
        }
        printf("%d\n",bla_now);
    }*/
}