Advertisement
leanchec

barcos.cpp

Aug 15th, 2023 (edited)
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.75 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. vector<pair<int, int>> adj[100010];//adjacencias da MST
  5. int dpmx[100100][21], dpa[100100][21];
  6. //dpmx[i][j] guarda o maximo de pessoas que conseguem sair do i e subir 1<<j(2^i) niveis
  7. //dpa[i][j] guarda o ancestral 1<<i de j
  8.  
  9. // struct para guardar as arestas originais
  10. struct Edge{
  11.     int u, v, mx;
  12.  
  13.     Edge(int a, int b, int m): u(a), v(b), mx(m){}
  14.  
  15.     bool operator < (Edge other){return this->mx>other.mx;}// sobrecarga do operador para usar o sort
  16. };
  17.  
  18. // dsu para o algoritno de Kruskal
  19. int pai[100100];
  20. int tam[100100];
  21. int nivel[100100];
  22.  
  23. int achar(int u){
  24.     if(u==pai[u])return u;
  25.     else return pai[u]=achar(pai[u]);
  26. }
  27.  
  28. void juntar(int u, int v){
  29.     u=pai[u];
  30.     v=pai[v];
  31.  
  32.     if(tam[u]>tam[v]){
  33.         pai[v]=u;
  34.         tam[u]+=tam[v];
  35.     }
  36.     else{
  37.         pai[u]=v;
  38.         tam[v]+=tam[u];
  39.     }
  40. }
  41.  
  42. //dfs para montar a arvore com raiz em 1 e montar os casos base da LCA
  43.  
  44. void dfs(int cur){
  45.     for(int i=0; i<adj[cur].size(); i++){
  46.         int v=adj[cur][i].first;
  47.         if(nivel[v]!=-1)continue;
  48.         dpa[v][0]=cur;
  49.         nivel[v]=nivel[cur]+1;
  50.         dpmx[v][0]=adj[cur][i].second;
  51.         dfs(v);
  52.     }
  53. }
  54.  
  55. int main(){
  56.     ios::sync_with_stdio(0); ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  57.     int n, b;
  58.     cin >> n >> b;
  59.  
  60.     vector<Edge> edges;
  61.     //leitura das arestas
  62.     for(int i=0; i<b; i++){
  63.         int a, b, mx;
  64.         cin >> a >> b >> mx;
  65.         Edge e(a, b, mx);
  66.         edges.push_back(e);
  67.     }
  68.  
  69.     //descobrindo a MST usando algoritmo de kruskal
  70.  
  71.     sort(edges.begin(), edges.end());
  72.  
  73.     //coloco os valores iniciais para o dsu e o enraizamento da arvore(LCA)
  74.  
  75.     for(int i=1; i<=n; i++){
  76.         pai[i]=i;
  77.         tam[i]=1;
  78.         nivel[i]=-1;
  79.     }
  80.  
  81.     for(int i=0; i<edges.size(); i++){
  82.             int u=edges[i].u, v=edges[i].v, mx=edges[i].mx;
  83.  
  84.             if(achar(u)==achar(v))continue;
  85.             juntar(u, v);
  86.             adj[u].push_back({v, mx});
  87.             adj[v].push_back({u, mx});
  88.     }
  89.  
  90.     //colocando os casos base da raiz e fazendo o dfs
  91.  
  92.     nivel[1]=0;
  93.     dpa[1][0]=1;
  94.     dpmx[1][0]=-1;
  95.     dfs(1);
  96.  
  97.     //dpa e igual ao ancestral do binary lifting, o ancestral 1<<i de j
  98.     /*
  99.     o maximo de pessoas que conseguem ir de j para 1<<i
  100.     e igual ao minimo entre o maximo de pessoas que conseguem
  101.     ir de j para 1<<(i-1) e o maximo de pessoas que conseguem
  102.     ir do ancestral 1<<(i-1) (dpa[j][i-1]) para o ancestral 1<<i,
  103.     que e o ancestral i<<(i-1) do dpa[j][i-1]
  104.     */
  105.  
  106.     for(int i=1; i<21; i++){
  107.         for(int j=1; j<=n; j++){
  108.             dpa[j][i]=dpa[dpa[j][i-1]][i-1];
  109.             dpmx[j][i]=min(dpmx[j][i-1], dpmx[dpa[j][i-1]][i-1]);
  110.         }
  111.     }
  112.  
  113.  
  114.     int c;
  115.     cin >> c;
  116.  
  117.     /*
  118.     para cada query crio um resp com um valor alto
  119.     e faco ele ser o minimo entre o seu valor atual
  120.     e o maximo de pessoas que conseguem passar pelo
  121.     caminho que vou percorrer durante a LCA
  122.     */
  123.  
  124.     for(int i=0; i<c; i++){
  125.         int x, y;
  126.         cin >> x >> y;
  127.         int resp=1e8;
  128.  
  129.         if(nivel[x]<nivel[y])swap(x, y);
  130.  
  131.         for(int i=20; i>=0; i--){
  132.             if(nivel[x]-(1<<i)>=nivel[y]){
  133.                 resp=min(resp, dpmx[x][i]);
  134.                 x=dpa[x][i];
  135.             }
  136.         }
  137.  
  138.         if(x==y){
  139.             cout << resp << endl;
  140.             continue;
  141.         }
  142.  
  143.         for(int i=20; i>=0; i--){
  144.             if(dpa[x][i]!=-1 && dpa[x][i]!=dpa[y][i]){
  145.                 resp=min({resp, dpmx[x][i], dpmx[y][i]});
  146.                 x=dpa[x][i];
  147.                 y=dpa[y][i];
  148.             }
  149.         }
  150.  
  151.         resp=min({resp, dpmx[x][0], dpmx[y][0]});
  152.  
  153.         cout << resp << endl;
  154.     }
  155.  
  156.     return 0;
  157. }
  158.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement