Pagini recente » Cod sursa (job #536504) | Cod sursa (job #588668) | Cod sursa (job #80776) | Cod sursa (job #801720) | Cod sursa (job #1813484)
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#define BUF_SIZE 16384
char buf[BUF_SIZE];
int pbuf=BUF_SIZE;
FILE*fi,*fo;
inline char nextch(){
if(pbuf==BUF_SIZE){
fread(buf, BUF_SIZE, 1, fi);
pbuf=0;
}
return buf[pbuf++];
}
inline long long nextnum(){
long long a=0;
char c=nextch();
while((c<'0' || c>'9') && c!='-')
c=nextch();
int semn=1;
if(c=='-'){
semn=-1;
c=nextch();
}
while('0'<=c && c<='9'){
a=a*10+c-'0';
c=nextch();
}
return a*semn;
}
#define MAXM 30000
#define MAXN 15000
#define MAXL 17
int maxdepth=0;
struct muchie{
int left;
int right;
int cost;
} M[1+MAXM];
int cmpM(muchie A, muchie B){
return (A.cost<B.cost);
}
struct Edge{
int dest;
int cost;
};
int fth[1+MAXN];
std::vector <Edge> G[1+MAXN];
inline int Union(int a, int b){
fth[b]=a;
}
int Find(int x){
if(fth[x]==x)
return x;
int y=Find(fth[x]);
fth[x]=y;
return y;
}
int euler[1+4*MAXN], ind;
int depth[1+2*MAXN];
int h[1+MAXN];
int firstapp[1+MAXN];
void getEuler(int node, int fth, int d){
if(d>maxdepth)
maxdepth=d;
euler[++ind]=node;
depth[ind]=d;
h[node]=d;
firstapp[node]=ind;
for(int i=0;i<G[node].size();i++)
if(G[node][i].dest!=fth){
getEuler(G[node][i].dest, node, d+1);
euler[++ind]=node;
depth[ind]=d;
}
}
int rmq[MAXL][2*MAXN];
int lg[2*MAXN];
void getRmq(){
for(int i=2;i<=ind;i++)
lg[i]=lg[i/2]+1;
for(int i=1;i<=ind;i++)
rmq[0][i]=i;
for(int i=1;(1<<i)<ind;i++)
for(int j=1;j<=ind-(1<<i);j++){
int l=1<<(i-1);
rmq[i][j]=rmq[i-1][j];
if(depth[rmq[i-1][j+l]]<depth[rmq[i][j]])
rmq[i][j]=rmq[i-1][j+l];
}
}
inline int lca(int x, int y){
int a=firstapp[x], b=firstapp[y];
if(a>b){int aux=a;a=b;b=aux;}
int diff=b-a+1;
int l=lg[diff];
int sol=rmq[l][a];
int sh=diff-(1<<l);
if(depth[sol]>depth[rmq[l][a+sh]])
sol=rmq[l][a+sh];
return euler[sol];
}
struct A{
int node;
int val;
} dp[MAXL][1+MAXN];
inline int maxim(int a, int b){
return a > b ? a : b;
}
inline int getRoad(int n){
for(int i=1;i<=n;i++)
for(int j=0;j<G[i].size();j++)
if(h[i]>h[G[i][j].dest]){
dp[0][i].node=G[i][j].dest;
dp[0][i].val=G[i][j].cost;
}
for(int log=1;(1<<log)<=maxdepth;log++)
for(int i=1;i<=n;i++){
dp[log][i].node=dp[log-1][dp[log-1][i].node].node;
dp[log][i].val=maxim(dp[log-1][i].val, dp[log-1][dp[log-1][i].node].val);
}
}
inline int maxOnRoad(int node, int height){
int max=0;
int log=0;
while((1<<log)<=height){
if(height&(1<<log)){
max=maxim(max, dp[log][node].val);
node=dp[log][node].node;
}
log++;
}
return max;
}
int main(){
fi=fopen("radiatie.in","r");
fo=fopen("radiatie.out","w");
int n=nextnum(), m=nextnum(), k=nextnum();
for(int i=1;i<=m;i++){
M[i].left=nextnum();
M[i].right=nextnum();
M[i].cost=nextnum();
}
std::sort(M+1, M+m+1, cmpM);
for(int i=1;i<=n;i++)
fth[i]=i;
for(int i=1;i<=m;i++)
if(Find(M[i].left)!=Find(M[i].right)){
Edge temp;
temp.dest=M[i].right;
temp.cost=M[i].cost;
G[M[i].left].push_back(temp);
temp.dest=M[i].left;
G[M[i].right].push_back(temp);
Union(Find(M[i].left), Find(M[i].right));
}
int root=n;
getEuler(root, 0, 1);
getRmq();
getRoad(n);
for(int i=0;i<k;i++){
int a=nextnum(), b=nextnum();
int l=lca(a, b);
fprintf(fo,"%d\n", maxim(maxOnRoad(a, h[a]-h[l]), maxOnRoad(b, h[b]-h[l])));
}
fclose(fi);
fclose(fo);
return 0;
}