Saturday, March 28, 2020

[Light OJ] 1384 - Stream My Contest

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : 1384 - Stream My Contest
Source            : Light Online Judge
Category          : Graph Theory
Algorithm         : Minimum Spanning Tree (Directed)
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2. #include "ext/pb_ds/assoc_container.hpp"  
  3. #include "ext/pb_ds/tree_policy.hpp"  
  4.   
  5. using namespace std;  
  6. using namespace __gnu_pbds;  
  7.   
  8. template <typename T> using order_set = tree <T, null_type, less <T>, rb_tree_tag, tree_order_statistics_node_update>;  
  9.   
  10. #define ll               long long int  
  11. #define endl             '\n'  
  12. #define pii              pair <int, int>  
  13.   
  14. static const int max_node = 1e3 + 5; // Maximum number of Node  
  15. static const int max_edge = 1e5 + 5; // Maximum number of Edge  
  16. static const int inf      = 1e9 + 9;  
  17.   
  18. struct Edge  
  19. {  
  20.       int u, v, w, band;  
  21.       Edge(int u = 0, int v = 0, int w = 0, int band = 0)  
  22.             : u(u), v(v), w(w), band(band) {}  
  23. };  
  24.   
  25. vector <Edge> edges;  
  26.   
  27. int directed_mst(int root, int nv, int max_band)  
  28. {  
  29. //      root = starting node  
  30. //      nv   = number of nodes, starting from 0  
  31. //      ne   = number of edges, starting from 0  
  32.   
  33.       vector <int> min_incoming(nv); // minimum weight among all incoming edges  
  34.       vector <int> pre(nv);          // parent of node v  
  35.       vector <int> cycle_id(nv);     // id of the corresponding cycle  
  36.       vector <int> vis(nv);          // used to determine cycle  
  37.       vector <Edge> tedges;          // temporary edges, which will be changed during finding mst  
  38.   
  39.       for (Edge e : edges) if (e.band >= max_band) tedges.push_back(e);  
  40.       int ne = tedges.size();  
  41.   
  42.       int dmst = 0;  
  43.       while (true)  
  44.       {  
  45.             for (int i = 0; i < nv; i++)  
  46.             {  
  47.                   min_incoming[i] = inf;  
  48.                   cycle_id[i] = -1;  
  49.                   vis[i] = -1;  
  50.             }  
  51.             for (int i = 0; i < ne; i++)  
  52.             {  
  53.                   int u = tedges[i].u;  
  54.                   int v = tedges[i].v;  
  55.                   int w = tedges[i].w;  
  56.                   if (u != v and w < min_incoming[v]) // Taking lowest incoming edge  
  57.                   {  
  58.                         min_incoming[v] = w;  
  59.                         pre[v] = u;  
  60.                   }  
  61.             }  
  62.             for (int i = 0; i < nv; i++)  
  63.             {  
  64.                   if (i == root) continue;  
  65.                   if (min_incoming[i] == inf) return -1; // Impossible case  
  66.             }  
  67.             min_incoming[root] = 0;  
  68.             pre[root] = root; // This need to set up, or can cause infinite loop  
  69.             int cnt_node = 0;  
  70.             for (int i = 0; i < nv; i++)  
  71.             {  
  72.                   dmst += min_incoming[i];  
  73.                   if (vis[i] == -1)  
  74.                   {  
  75.                         int v = i;  
  76.                         while (vis[v] == -1)  
  77.                         {  
  78.                               vis[v] = i;  
  79.                               v = pre[v];  // climbing up  
  80.                         }  
  81.                         if (v == root or vis[v] != i) continue;  
  82.                         cycle_id[v] = cnt_node; // new cycle, put all the member in same id  
  83.                         for (int u = pre[v]; u != v; u = pre[u]) cycle_id[u] = cnt_node;  
  84.                         cnt_node++;  
  85.                   }  
  86.             }  
  87.             if (cnt_node == 0) break;  
  88.             for (int i = 0; i < nv; i++)  
  89.             {  
  90.                   if (cycle_id[i] == -1) cycle_id[i] = cnt_node++;  
  91.             }  
  92.             for (int i = 0; i < ne; i++)  
  93.             {  
  94.                   int tmp = tedges[i].v;  
  95.                   tedges[i].u = cycle_id[ tedges[i].u ];  
  96.                   tedges[i].v = cycle_id[ tedges[i].v ];  
  97.                   if (tedges[i].u != tedges[i].v) tedges[i].w -= min_incoming[tmp];  
  98.             }  
  99.             nv = cnt_node;  
  100.             root = cycle_id[root];  
  101.       }  
  102.       return dmst;  
  103. }  
  104.   
  105.   
  106. signed main()  
  107. {  
  108.       ios_base::sync_with_stdio(false);  
  109.       cin.tie(nullptr);  
  110.   
  111.       #ifndef ONLINE_JUDGE  
  112.             freopen("in.txt""r", stdin);  
  113.       #endif // ONLINE_JUDGE  
  114.   
  115.       int tc;  
  116.       cin >> tc;  
  117.       for (int tcase = 1; tcase <= tc; tcase++)  
  118.       {  
  119.             int tnode, tedge, tcost;  
  120.             cin >> tnode >> tedge >> tcost;  
  121.             edges.clear();  
  122.             edges.resize(tedge);  
  123.             for (Edge &x : edges) cin >> x.u >> x.v >> x.band >> x.w;  
  124.             int lo = 0;  
  125.             int hi = 1e6;  
  126.             int max_band = -1;  
  127.             while (lo <= hi)  
  128.             {  
  129.                   int mid = lo + hi >> 1;  
  130.                   int dmst = directed_mst(0, tnode, mid);  
  131.                   if (dmst >= 0 and dmst <= tcost) max_band = mid, lo = mid + 1;  
  132.                   else hi = mid - 1;  
  133.             }  
  134.             cout << "Case " << tcase << ": ";  
  135.             if (max_band == -1) cout << "impossible" << endl;  
  136.             else cout << max_band << " kbps" << endl;  
  137.       }  
  138. }