mr_dot_convict

11228-Transportation-system-UVa-mr.convict

May 16th, 2019
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.89 KB | None | 0 0
  1. /*author* Priyanshu Shrivastav (from IIT Palakkad) *
  2.  * *_ __ ___  _ ______ ___  _ ____   ___  ___| |_  *
  3.  * | '_ ` _ \| '__/ __/ _ \| '_ \ \ / / |/ __| __| *
  4.  * | | | | | | | | (_| (_) | | | \ V /| | (__| |_  *
  5.  * |_| |_| |_|_|(_)___\___/|_| |_|\_/ |_|\___|\__| *
  6. When I wrote this, only God and I understood what I was doing
  7.  ** * * * * * * * Now, only God knows * * * * * * */
  8. #include         <bits/stdc++.h>
  9. #pragma GCC      optimize ("Ofast")
  10. #pragma GCC      optimize ("unroll-loops")
  11. #pragma GCC      target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  12.  
  13. #define IOS      ios_base::sync_with_stdio(false); cin.tie (nullptr)
  14. #define PREC     cout.precision (10); cout << fixed
  15. #define bg(x)    "[ " << #x << " : " << x << " ]"
  16. #define x        first
  17. #define y        second
  18. using namespace std;
  19. using ld = long double;
  20. using pild = pair <int, long double>;
  21.  
  22. const int N = 1005;
  23. const long double eps = 1e-9;
  24.  
  25. vector < vector < pild> > Adj;
  26. vector < vector < int > > ConComp;
  27. vector <pair <ld, ld>> point;
  28. int n, r, cn, CC[N];
  29. bool vis[N];
  30.  
  31. struct Edge {
  32.    int u, v;
  33.    long double w;
  34.    inline bool operator < (const Edge &o) const {
  35.       return w  + eps < o.w;
  36.    }
  37. };
  38.  
  39. vector <Edge> edges;
  40. int rep[N], rnk[N];
  41.  
  42. void makeSet() {
  43.    for(int i = 0; i < n; ++i)
  44.       rep[i] = i, rnk[i] = 0;
  45. }
  46.  
  47. int findSet(int u) {
  48.    int ru = u;
  49.    while (ru != rep[ru])
  50.       ru = rep[ru];
  51.  
  52.    while (u != rep[u]) {
  53.       int tmp = rep[u];
  54.       rep[u] = ru;
  55.       u = tmp;
  56.    }
  57.    return ru;
  58. }
  59.  
  60. void mergeSet(int u, int v) {
  61.    int ru = findSet(u), rv = findSet(v);
  62.    if (rnk[ru] > rnk[rv]) rep[rv] = rep[ru];
  63.    else rep[ru] = rep[rv];
  64.  
  65.    if (rnk[ru] == rnk[rv])
  66.       ++rnk[rv];
  67. }
  68.  
  69. long double kruskals () {
  70.    long double cost = 0;
  71.    sort (edges.begin(), edges.end());
  72.    int cnt = 0;
  73.  
  74.    for (Edge e : edges) {
  75.       int u = e.u, v = e.v;
  76.       long double w = e.w;
  77.       if (findSet(u) == findSet(v)) continue;
  78.       cost += w;
  79.       mergeSet(u, v);
  80.       ++cnt;
  81.    }
  82.  
  83.    return cost;
  84. }
  85.  
  86. inline long double wt (int u, int v) {
  87.    ld w = hypot(point[u].x - point[v].x, point[u].y - point[v].y);
  88.    return w;
  89. }
  90.  
  91. void dfs (int u, int cc) {
  92.    vis[u] = true;
  93.    CC[u] = cc;
  94.    ConComp[cc].push_back(u);
  95.    for (auto vPair : Adj[u]) {
  96.       int v = vPair.x;
  97.       if (!vis[v]) dfs (v, cc);
  98.    }
  99. }
  100.  
  101. void solve(int tc) {
  102.    cn = 0;
  103.    fill(vis, vis + n, false);
  104.    fill(CC, CC + n, -1);
  105.  
  106.    for (int i = 0; i < n; ++i) {
  107.       if (!vis[i]) dfs (i, cn++);
  108.    }
  109.  
  110.    cout << "Case #" << tc << ": " << cn << ' ';
  111.  
  112.    makeSet();
  113.    ld ans = 0;
  114.    for (int i = 0; i < cn; ++i) {
  115.       edges.clear();
  116.       for (int j = 0; j < (int)ConComp[i].size(); ++j) {
  117.          for (int k = j + 1; k < (int)ConComp[i].size(); ++k) {
  118.             int u = ConComp[i][j], v = ConComp[i][k];
  119.             edges.push_back({u, v, wt(u, v)});
  120.          }
  121.       }
  122.       ans += kruskals();
  123.    }
  124.    cout << (int)(ans + 0.5) << ' ';
  125.  
  126.    edges.clear();
  127.  
  128.    for (int u = 0; u < n; ++u) {
  129.       for (int v = 0; v < n; ++v) {
  130.          if (u == v || wt(u, v) < r + eps) continue;
  131.          ld w = wt(u, v);
  132.          edges.push_back({u, v, w});
  133.       }
  134.    }
  135.  
  136.    ans = kruskals();
  137.    cout << (int)(ans + 0.5) << '\n';
  138. }
  139.  
  140. void read() {
  141.    cin >> n >> r;
  142.    Adj.assign(n, vector <pild> ());
  143.    point.assign(n, pair <ld, ld>());
  144.    ConComp.assign(n, vector <int> ());
  145.    for (int i = 0; i < n; ++i) {
  146.       cin >> point[i].x >> point[i].y;
  147.    }
  148.  
  149.    for (int i = 0; i < n; ++i) {
  150.       for (int j = 0; j < n; ++j) {
  151.          if (i == j) continue;
  152.          if (wt(i, j) < r + eps) {
  153.             Adj[i].push_back(pild(j, wt(i, j)));
  154.             Adj[j].push_back(pild(i, wt(i, j)));
  155.          }
  156.       }
  157.    }
  158. }
  159.  
  160. signed main() {
  161.    int tc;
  162.    cin >> tc;
  163.    for (int i = 1; i <= tc; ++i) {
  164.       read();
  165.       solve(i);
  166.    }
  167.  
  168.    return EXIT_SUCCESS;
  169. }
Add Comment
Please, Sign In to add comment