Dang_Quan_10_Tin

SWAPPING

Aug 19th, 2020 (edited)
306
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.99 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <vector>
  4. #include <cmath>
  5. #include <algorithm>
  6. #include <cstring>
  7. #define task ""
  8. using namespace std;
  9. using ll = int;
  10. using ld = long double;
  11.  
  12. const int N = 5e2 + 2;
  13. const ll Inf = 1e9;
  14. int x[N], y[N], node[N][N], lab[N * N], ranks[N * N];
  15. bool chosen[N][N];
  16. ll d[N * N], maxn[N * N][19];
  17. pair<int, int> a[N * N];
  18. int n, m, l(0), par[N * N][19], q;
  19. vector<int> exist, adj[N * N], ck[N];
  20.  
  21. #define sqr(x) ((x) * (x))
  22.  
  23. ll dis(int i, int j)
  24. {
  25.     return sqr(x[i] - x[j]) + sqr(y[i] - y[j]);
  26. }
  27.  
  28. void Read()
  29. {
  30.     cin >> n;
  31.     for (int i = 1; i <= n; ++i)
  32.         cin >> x[i] >> y[i];
  33.     for (int i = 1; i <= n; ++i)
  34.         for (int j = 1; j <= n; ++j)
  35.             node[i][j] = ++l,
  36.             a[l] = {i, j},
  37.             d[l] = dis(i, j),
  38.             exist.push_back(l);
  39.     cin >> m;
  40.     for (int i = 1; i <= m; ++i)
  41.     {
  42.         int u, v;
  43.         cin >> u >> v;
  44.         ck[u].push_back(v);
  45.         ck[v].push_back(u);
  46.     }
  47.     //cerr << "\n";
  48. }
  49.  
  50. int findpar(int v)
  51. {
  52.     return lab[v] < 0 ? v : lab[v] = findpar(lab[v]);
  53. }
  54.  
  55. void Union(int u, int v)
  56. {
  57.     lab[u] += lab[v];
  58.     lab[v] = u;
  59. }
  60.  
  61. void dfs(int v)
  62. {
  63.     for (int i = 1; i <= log2(ranks[v]); ++i)
  64.         par[v][i] = par[par[v][i - 1]][i - 1],
  65.         maxn[v][i] = min(maxn[v][i - 1], maxn[par[v][i - 1]][i - 1]);
  66.     for (auto i : adj[v])
  67.         if (!ranks[i])
  68.         {
  69.             par[i][0] = v;
  70.             maxn[i][0] = d[v];
  71.             ranks[i] = ranks[v] + 1;
  72.             dfs(i);
  73.         }
  74. }
  75.  
  76. void Make_tree()
  77. {
  78.     memset(lab, -1, sizeof lab);
  79.     fill_n(&maxn[0][0], 19 * N * N, Inf);
  80.     sort(exist.begin(), exist.end(), [&](int &x, int &y) { return d[x] > d[y]; });
  81.     //cerr << "Sort ok\n";
  82.     for (auto i : exist)
  83.     {
  84.         int x = a[i].first,
  85.             y = a[i].second,
  86.             u = findpar(i);
  87.         for (auto j : ck[x])
  88.         {
  89.             if (chosen[j][y])
  90.             {
  91.                 int v = findpar(node[j][y]);
  92.                 if (u != v)
  93.                 {
  94.                     adj[node[j][y]].push_back(i);
  95.                     adj[i].push_back(node[j][y]);
  96.                     Union(u, v);
  97.                 }
  98.             }
  99.         }
  100.         for (auto j : ck[y])
  101.         {
  102.             if (chosen[x][j])
  103.             {
  104.                 int v = findpar(node[x][j]);
  105.                 if (u != v)
  106.                 {
  107.                     adj[node[x][j]].push_back(i);
  108.                     adj[i].push_back(node[x][j]);
  109.                     Union(u, v);
  110.                 }
  111.             }
  112.         }
  113.         chosen[x][y] = 1;
  114.     }
  115.     //cerr << "Edge ok\n";
  116.     for (int i = 1; i <= n * n; ++i)
  117.         if (!ranks[i])
  118.         {
  119.             ranks[i] = 1;
  120.             dfs(i);
  121.         }
  122. }
  123.  
  124. ll LCA(int u, int v)
  125. {
  126.     if (ranks[u] < ranks[v])
  127.         swap(u, v);
  128.     ll ans = min(d[u], d[v]);
  129.     for (int i = log2(ranks[u]); ~i; --i)
  130.         if (ranks[par[u][i]] >= ranks[v])
  131.         {
  132.             ans = min(ans, maxn[u][i]);
  133.             u = par[u][i];
  134.         }
  135.     for (int i = log2(ranks[u]); ~i; --i)
  136.         if (par[u][i] != par[v][i])
  137.         {
  138.             ans = min(ans, min(maxn[u][i], maxn[v][i]));
  139.             u = par[u][i];
  140.             v = par[v][i];
  141.         }
  142.     while (u != v)
  143.     {
  144.         ans = min(ans, min(maxn[u][0], maxn[v][0]));
  145.         u = par[u][0];
  146.         v = par[v][0];
  147.     }
  148.     return ans;
  149. }
  150.  
  151. void Solve()
  152. {
  153.     int a, b;
  154.     cin >> a >> b;
  155.     int u = node[a][b],
  156.         v = node[b][a];
  157.     cout << LCA(u, v) << "\n";
  158. }
  159.  
  160. int32_t main()
  161. {
  162.     ios::sync_with_stdio(0);
  163.     cin.tie(0);
  164.     cout.tie(0);
  165.     if (fopen(task ".INP", "r"))
  166.         freopen(task ".INP", "r", stdin),
  167.             freopen(task ".OUT", "w", stdout);
  168.     Read();
  169.     //cerr << "Read ok\n";
  170.     Make_tree();
  171.     //cerr << "Make_tree ok\n";
  172.     for (cin >> q; q--;)
  173.         Solve();
  174. }
  175. /*
  176. 6
  177. 0 0
  178. -1 3
  179. -1 0
  180. -1 -3
  181. 3 0
  182. 0 1
  183. 6
  184. 1 2
  185. 2 3
  186. 3 4
  187. 4 1
  188. 1 5
  189. 5 6
  190. 5
  191. 6 5
  192. 2 4
  193. 2 6
  194. 3 6
  195. 4 6
  196. */
Advertisement
Add Comment
Please, Sign In to add comment