Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define MAX 10007
- #define LOG 20
- using namespace std;
- typedef long long ll;
- typedef pair<int, int> ii;
- int parent[LOG][MAX];
- int level[MAX], vis[MAX], dist[MAX],n;
- vector<ii> graph[MAX];
- void dfs(int no){
- vis[no] = true;
- for(int v = 0; v < graph[no].size(); v++){
- int folha = graph[no][v].first;
- if(!vis[folha]){
- level[folha] = level[no] + 1;
- parent[0][folha] = no;
- dist[folha] = dist[no] + graph[no][v].second;
- dfs(folha);
- }
- }
- }
- void build(int no){
- parent[0][no] = no;
- for(int i = 1; (1 << i) <= n; i++){
- for(int j = 1; j <= n; j++){
- if(parent[i-1][j]) parent[i][j] = parent[i-1][parent[i-1][j]];
- //dist[i][j] = dist[i-1][j] + dist[i-1][parent[i-1][j]];
- }
- }
- }
- int lca(int u, int v){
- if(level[u] < level[v]) swap(u, v);
- int lg;
- for(lg = 1; (1 << lg) <= level[u]; lg++);
- for(int i = lg-1; i >= 0; i--){
- if(level[u]-(1 << i) >= level[v]){
- //sum += dist[i][u];
- u = parent[i][u];
- }
- }
- if(u == v) return u;
- for(int i = lg-1; i >= 0; i--){
- if(parent[i][u] != parent[i][v]){
- //sum += dist[i][u] + dist[i][v];
- u = parent[i][u];
- v = parent[i][v];
- }
- }
- //sum += dist[0][u] + dist[0][v];
- //cout << sum << endl;
- return parent[0][u];
- }
- int find(int a, int c){
- int lg;
- for(lg = 1; (1 << lg) <= level[a]; lg++)
- for(int i = lg-1; i >= 0; i--){
- if(level[a]-(1 << i) >= c){
- a = parent[i][a];
- }
- }
- return a;
- }
- void clear(){
- memset(parent, 0, sizeof parent);
- memset(vis, 0, sizeof vis);
- memset(level, 0, sizeof level);
- for(int i = 0; i <= n; i++) {
- graph[i].clear();
- dist[i] = 0;
- }
- }
- int main(){
- int t; scanf("%d", &t);
- while(t--){
- scanf("%d", &n);
- clear();
- for(int i = 0; i < n-1; i++){
- int a, b, c; scanf("%d %d %d", &a, &b, &c);
- graph[a].push_back(make_pair(b,c));
- graph[b].push_back(make_pair(a, c));
- }
- dfs(1); build(1);
- //for(int i = 1; i <= n; i++) cout << level[i] << " ";
- //cout << endl;
- char type[10];
- while(true){
- scanf("%s", type);
- if(type[1] == 'O') break;
- int a, b; scanf("%d %d", &a, &b);
- int incesto = lca(a, b);
- if(type[1] == 'I'){
- //cout << "osh\n";
- printf("%d\n", dist[a]+dist[b]-2*dist[incesto]);
- }else if(type[1] == 'T'){
- int c; scanf("%d", &c);
- int dif = level[a]-level[incesto]+1;
- //cout << dif << endl;
- //cout << level[incesto] << " " << level[a] << endl;
- if(dif >= c ){
- //cout << level[a]-c << endl;
- printf("%d\n", find(a,level[a]-c+1));
- }else {
- //cout << level[incesto]+c-dif << endl;
- printf("%d\n", find(b, 2*level[incesto]+c-level[a]-1));
- }
- }
- }
- printf("\n");
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement