Nu aveti permisiuni pentru a descarca fisierul grader_test24.ok
Cod sursa(job #7756)
Utilizator | Data | 22 ianuarie 2007 16:12:45 | |
---|---|---|---|
Problema | Radiatie | Scor | 0 |
Compilator | cpp | Status | done |
Runda | Arhiva de probleme | Marime | 4.16 kb |
#include <stdio.h>
#include <stdlib.h>
#define infile "radiatie.in"
#define outfile "radiatie.out"
#define NMAX 15005
#define MCHMAX 30005
struct muchie{int u,v,c;};
struct NOD{int x,c; struct NOD *adr;};
FILE *fin,*fout;
int n,m,k;
muchie mch[MCHMAX];
char used[MCHMAX];
int precarb[NMAX];
NOD *prim[NMAX];
char vizitat[NMAX];
int prec[NMAX],niv[NMAX],cost[NMAX];
int stramos[15][NMAX],radiatie[15][NMAX];
inline int cmp(const void *ma, const void *mb)
{
muchie a=*((muchie *)ma);
muchie b=*((muchie *)mb);
return -(a.c<b.c)+(a.c>b.c);
}
inline void adaug_st(NOD *(&prim), int x, int c)
{
NOD *a=new NOD;
a->x=x;
a->c=c;
a->adr=prim;
prim=a;
}
int root(int u)
{
if(precarb[u]<0)
return u;
return root(precarb[u]);
}
inline void uneste(int rad1, int rad2)
{
if(precarb[rad1]<precarb[rad2]) // adica rad1 are adancime mai mare decat rad2
precarb[rad2]=rad1;
else
if(precarb[rad1]>precarb[rad2]) // adica rad2 are adancime mai mare decat rad1
precarb[rad1]=rad2;
else // rad1 si rad2 au aceleasi adancimi
{
precarb[rad1]=rad2;
precarb[rad2]--;
}
}
inline int max(int x, int y)
{
return (x>y)?x:y;
}
void df(int varf, int nivel)
{
NOD *b=prim[varf];
while(b)
{
if(!vizitat[b->x])
{
vizitat[b->x]=1;
prec[b->x]=varf;
niv[b->x]=nivel+1;
cost[b->x]=b->c;
df(b->x,nivel+1);
}
b=b->adr;
}
}
inline int poz_2(int x)
{
if(x>>1)
return poz_2(x>>1)+1;
else
return 1;
}
void cauta_stramos(int n, int varf, int &tata, int &rad)
{
int rang,rang_ini;
tata=varf;
rad=0;
while(n)
{
rang_ini=rang=n^(n&(n-1));
rang=poz_2(rang);
rad=max(rad,radiatie[rang-1][tata]);
tata=stramos[rang-1][tata];
n-=rang_ini;
}
}
int interogare(int u, int v)
{
int maxim=0,maxim2=0,i,gasit=0;
if(niv[u]>niv[v])
cauta_stramos(niv[u]-niv[v],u,u,maxim);
if(niv[v]>niv[u])
cauta_stramos(niv[v]-niv[u],v,v,maxim2);
maxim=max(maxim,maxim2);
if(u==v)
return maxim;
i=0;
while(i<=14 && !gasit)
if(stramos[i][u]==stramos[i][v])
gasit=1;
else
i++;
if(!i)
{
maxim=max(maxim,radiatie[i][u]);
maxim=max(maxim,radiatie[i][v]);
return maxim;
}
//i--;
//maxim=max(maxim,radiatie[i][u]);
//maxim=max(maxim,radiatie[i][v]);
//maxim=max(maxim,interogare(stramos[i][u],stramos[i][v]));
return maxim;
}
int main()
{
int i,j;
fin=fopen(infile,"r");
fout=fopen(outfile,"w");
fscanf(fin,"%d %d %d",&n,&m,&k);
for(i=0;i<m;i++)
{
fscanf(fin,"%d %d %d",&mch[i].u,&mch[i].v,&mch[i].c);
mch[i].u--;
mch[i].v--;
}
qsort(mch,m,sizeof(muchie),cmp);
// Kruskal
for(i=0;i<m;i++)
used[i]=0;
for(i=0;i<n;i++)
precarb[i]=-1;
int ru,rv;
for(i=0;i<m;i++)
{
ru=root(mch[i].u);
rv=root(mch[i].v);
if(ru!=rv)
{
uneste(ru,rv);
used[i]=1;
}
}
// construire arbore
for(i=0;i<n;i++)
prim[i]=NULL;
for(i=0;i<m;i++)
if(used[i])
{
adaug_st(prim[mch[i].u],mch[i].v,mch[i].c);
adaug_st(prim[mch[i].v],mch[i].u,mch[i].c);
}
for(i=0;i<n;i++)
vizitat[i]=0;
for(i=0;i<n;i++)
if(!vizitat[i])
{
vizitat[i]=1;
prec[i]=-1;
niv[i]=0;
df(i,0);
}
// preprocesare stramosi => se calculeaza, pentru fiecare varf, stramosii de ordin 2^k si radiatia pana la ele
for(j=0;j<n;j++)
{
stramos[0][j]=prec[j];
if(prec[j]==-1)
radiatie[0][j]=-1;
else
radiatie[0][j]=cost[j];
}
for(i=1;i<=14;i++)
for(j=0;j<n;j++)
if(stramos[i-1][j]==-1)
stramos[i][j]=radiatie[i][j]=-1;
else
{
stramos[i][j]=stramos[i-1][stramos[i-1][j]];
if(stramos[i][j]==-1)
radiatie[i][j]=-1;
else
radiatie[i][j]=max(radiatie[i-1][j],radiatie[i-1][stramos[i-1][j]]);
}
// rezolvarea interogarilor
int u,v;
for(i=0;i<k;i++)
{
fscanf(fin,"%d %d",&u,&v);
u--;v--;
fprintf(fout,"%d\n",interogare(u,v));
fclose(fout);
fout=fopen(outfile,"a");
}
fclose(fin);
fclose(fout);
return 0;
}