Pagini recente » Cod sursa (job #2807893) | Cod sursa (job #2433054) | Cod sursa (job #2688223) | Cod sursa (job #1340492) | Cod sursa (job #2928003)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("radiatie.in");
ofstream fout ("radiatie.out");
const int MAX_M = 30005;
const int MAX_N = 15005;
int n, m, q, qu, qv;
struct EDGE{
int u, v, c;
inline bool operator < (const EDGE &rhs) const{
return c < rhs.c;
}
} input;
struct APM{
public: vector <EDGE> edge;
private: int tata[MAX_N], cost[MAX_N];
private: int rnod;
private: inline int root(const int &nod){
rnod = nod;
while(tata[rnod] != 0)
rnod = tata[rnod];
return rnod;
}
private: inline void redirect(int nod, int parent){
if(tata[nod] != 0)
redirect(tata[nod], nod);
tata[nod] = parent;
cost[nod] = cost[parent];
}
private: int ru, rv;
private: inline void join(EDGE my_edge){
ru = root(my_edge.u);
rv = root(my_edge.v);
if(ru != rv){
/// dau redirect drumului dintre ru si my_edge.u
redirect(my_edge.u, 0);
/// dau redirect drumului dintre rv si my_edge.v
redirect(my_edge.v, 0);
tata[my_edge.u] = my_edge.v;
cost[my_edge.u] = my_edge.c;
}
}
private: int lvl[MAX_N];
private: inline void set_lvl(int crt, int level){
lvl[crt] = level;
for(auto nxt : fii[crt])
set_lvl(nxt, level+1);
}
private: int radacina;
private: int ancestor[14][MAX_N], maximum[14][MAX_N], pw2[14], lg2[MAX_N];
private: vector <int> fii[MAX_N];
public: inline void build(){
sort(edge.begin(), edge.end());
for(auto muchie : edge)
join(muchie);
lg2[0] = lg2[1] = 0;
for(int i=2; i<=n; i++)
lg2[i] = lg2[i / 2] + 1;
pw2[0] = 1;
for(int i=1; i<=lg2[n]; i++)
pw2[i] = (pw2[i-1] << 1);
for(int j=1; j<=n; j++){
ancestor[0][j] = tata[j];
maximum[0][j] = cost[j];
}
for(int i=1; i<=lg2[n]; i++){
for(int j=1; j<=n; j++){
ancestor[i][j] = ancestor[i-1][ancestor[i-1][j]];
maximum[i][j] = max(maximum[i-1][j], maximum[i-1][ancestor[i-1][j]]);
}
}
for(int i=1; i<=n; i++){
if(tata[i] == 0)
radacina = i;
else
fii[tata[i]].push_back(i);
}
set_lvl(radacina, 1);
}
private: inline int stramos(int nod, int dist){
int pw2 = 0;
while(dist != 0){
if(dist & 1)
nod = ancestor[pw2][nod];
pw2++;
dist >>= 1;
}
return nod;
}
private: int st, md, dr, save, snod1, snod2;
private: inline int lca(int nod1, int nod2){
if(lvl[nod1] < lvl[nod2])
swap(nod1, nod2);
nod1 = stramos(nod1, lvl[nod1] - lvl[nod2]);
st = 0;
save = dr = lvl[nod1]-1;
while(st <= dr){
md = (st + dr) / 2;
snod1 = stramos(nod1, md);
snod2 = stramos(nod2, md);
if(snod1 == snod2){
save = md;
dr = md - 1;
}else
st = md + 1;
}
return stramos(nod1, save);
}
private: inline int get_max(int nod, int parent){
int answer = 0, pw2 = 0, dist = lvl[nod] - lvl[parent];
while(dist != 0){
if(dist & 1){
answer = max(answer, maximum[pw2][nod]);
nod = ancestor[pw2][nod];
}
pw2++;
dist >>= 1;
}
return answer;
}
private: int lcaUV;
public: inline int query(const int &u, const int &v){
lcaUV = lca(u, v);
return max(get_max(u, lcaUV), get_max(v, lcaUV));
}
} tree;
int main (){
ios_base::sync_with_stdio(false);
fin.tie(nullptr), fout.tie(nullptr);
fin>>n>>m>>q;
for(int i=1; i<=m; i++){
fin>>input.u>>input.v>>input.c;
tree.edge.push_back(input);
}
tree.build();
while(q--){
fin>>qu>>qv;
fout<<tree.query(qu, qv)<<"\n";
}
return 0;
}
/**
**/