Friday, February 8, 2019

[Gym] 102021M - Mountaineers

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : 102021M - Mountaineers
Source            : Codeforces Gym
Category          : Graph Theory
Algorithm         : Minimum Spanning Tree, LCA
Verdict           : Accepted
Minimum Spanning Tree from 2D grid.

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. #define pii       pair <int, int>  
  6.   
  7. static const int maxn = 500 + 5;  
  8. static const int Max = 500 * 500 + 5;  
  9. static const int logn = 16;  
  10.   
  11. int dr[] = {+0, -1, +0, +1};  
  12. int dc[] = {-1, +0, +1, +0};  
  13.   
  14. struct Edge  
  15. {  
  16.     int u, v, w;  
  17.     Edge(int u = 0, int v = 0, int w = 0) : u(u), v(v), w(w) {}  
  18.     friend bool operator < (Edge A, Edge B)  
  19.     {  
  20.         return A.w < B.w;  
  21.     }  
  22. };  
  23.   
  24. struct Node  
  25. {  
  26.     int v, w;  
  27.     Node(int v = 0, int w = 0) : v(v), w(w) {}  
  28. };  
  29.   
  30. vector <Edge> Edges;  
  31. int which_node[maxn][maxn], wgt[maxn][maxn];  
  32. int par[Max];  
  33.   
  34. vector <Node> graph[Max];  
  35.   
  36. void makeSet()  
  37. {  
  38.     for (int i = 1; i < Max; i++) par[i] = i;  
  39. }  
  40.   
  41. int findRep(int r)  
  42. {  
  43.     if (r == par[r]) return r;  
  44.     return par[r] = findRep(par[r]);  
  45. }  
  46.   
  47. void kruskal()  
  48. {  
  49.     makeSet();  
  50.     sort(Edges.begin(), Edges.end());  
  51.     for (Edge E : Edges)  
  52.     {  
  53.         int u = E.u;  
  54.         int v = E.v;  
  55.         int w = E.w;  
  56.         int p = findRep(u);  
  57.         int q = findRep(v);  
  58.         if (p != q)  
  59.         {  
  60.             graph[u].emplace_back(v, w);  
  61.             graph[v].emplace_back(u, w);  
  62.             par[q] = p;  
  63.         }  
  64.     }  
  65. }  
  66.   
  67. struct info  
  68. {  
  69.     int f, w;  
  70.     info(int f = 0, int w = 0) : f(f), w(w) {}  
  71. };  
  72.   
  73. int depth[Max];  
  74. info father[Max][logn];  
  75.   
  76. void dfs(int u = 1, int p = -1)  
  77. {  
  78.     for (int i = 1; i < logn; i++)  
  79.     {  
  80.         int f = father[u][i-1].f;  
  81.         father[u][i].f = father[f][i-1].f;  
  82.         father[u][i].w = max(father[f][i-1].w, father[u][i-1].w);  
  83.     }  
  84.     for (Node g : graph[u])  
  85.     {  
  86.         int v = g.v;  
  87.         int w = g.w;  
  88.         if (v == p) continue;  
  89.         depth[v] = depth[u] + 1;  
  90.         father[v][0].f = u;  
  91.         father[v][0].w = w;  
  92.         dfs(v, u);  
  93.     }  
  94. }  
  95.   
  96. pii findLCA(int u, int v)  
  97. {  
  98.     if (depth[u] < depth[v]) swap(u, v);  
  99.     int maxi = -1;  
  100.     for (int i = logn-1; i >= 0; i--)  
  101.     {  
  102.         if (depth[father[u][i].f] >= depth[v])  
  103.         {  
  104.             maxi = max(maxi, father[u][i].w);  
  105.             u = father[u][i].f;  
  106.         }  
  107.     }  
  108.     if (u == v) return pii(u, maxi);  
  109.     for (int i = logn-1; i >= 0; i--)  
  110.     {  
  111.         if (father[u][i].f != father[v][i].f)  
  112.         {  
  113.             maxi = max(maxi, father[u][i].w);  
  114.             maxi = max(maxi, father[v][i].w);  
  115.             u = father[u][i].f;  
  116.             v = father[v][i].f;  
  117.         }  
  118.     }  
  119.     maxi = max(maxi, father[u][0].w);  
  120.     maxi = max(maxi, father[v][0].w);  
  121.     return pii(father[u][0].f, maxi);  
  122. }  
  123.   
  124. int main()  
  125. {  
  126.     //freopen("in.txt", "r", stdin);  
  127.   
  128.     ios_base::sync_with_stdio(false);  
  129.     cin.tie(nullptr);  
  130.   
  131.     int row, column, query;  
  132.     cin >> row >> column >> query;  
  133.     int ptr = 0;  
  134.     for (int i = 1; i <= row; i++)  
  135.     {  
  136.         for (int j = 1; j <= column; j++)  
  137.         {  
  138.             which_node[i][j] = ++ptr;  
  139.             cin >> wgt[i][j];  
  140.         }  
  141.     }  
  142.     for (int i = 1; i <= row; i++)  
  143.     {  
  144.         for (int j = 1; j <= column; j++)  
  145.         {  
  146.             int u = which_node[i][j];  
  147.             for (int k = 0; k < 4; k++)  
  148.             {  
  149.                 int x = i + dr[k];  
  150.                 int y = j + dc[k];  
  151.                 bool valid = (x >= 1 && x <= row && y >= 1 && y <= column);  
  152.                 if (valid)  
  153.                 {  
  154.                     int v = which_node[x][y];  
  155.                     int w = max(wgt[i][j], wgt[x][y]);  
  156.                     Edges.emplace_back(u, v, w);    
  157.                 }  
  158.             }  
  159.         }  
  160.     }  
  161.     kruskal();  
  162.     depth[1] = 1;  
  163.     dfs();  
  164.     while (query--)  
  165.     {  
  166.         int x1, y1, x2, y2;  
  167.         cin >> x1 >> y1 >> x2 >> y2;  
  168.         int u = which_node[x1][y1];  
  169.         int v = which_node[x2][y2];  
  170.         if (u == v)  
  171.         {  
  172.             cout << wgt[x1][y1] << endl;  
  173.             continue;  
  174.         }  
  175.         pii ans = findLCA(u, v);  
  176.         assert(ans.second != -1);   
  177.         cout << ans.second << endl;  
  178.     }  
  179. }  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.