Saturday, March 28, 2020

[UVA] 11183 - Teen Girl Squad

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : 11183 - Teen Girl Squad
Source            : UVA 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;  
  21.       Edge(int u = 0, int v = 0, int w = 0)  
  22.             : u(u), v(v), w(w) {}  
  23. };  
  24.   
  25. vector <Edge> edges;  
  26.   
  27. int directed_mst(int root, int nv, int ne)  
  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(ne);      // temporary edges, which will be changed during finding mst  
  38.   
  39.       tedges = edges;  
  40.       int dmst = 0;  
  41.       while (true)  
  42.       {  
  43.             for (int i = 0; i < nv; i++)  
  44.             {  
  45.                   min_incoming[i] = inf;  
  46.                   cycle_id[i] = -1;  
  47.                   vis[i] = -1;  
  48.             }  
  49.             for (int i = 0; i < ne; i++)  
  50.             {  
  51.                   int u = tedges[i].u;  
  52.                   int v = tedges[i].v;  
  53.                   int w = tedges[i].w;  
  54.                   if (u != v and w < min_incoming[v]) // Taking lowest incoming edge  
  55.                   {  
  56.                         min_incoming[v] = w;  
  57.                         pre[v] = u;  
  58.                   }  
  59.             }  
  60.             for (int i = 0; i < nv; i++)  
  61.             {  
  62.                   if (i == root) continue;  
  63.                   if (min_incoming[i] == inf) return -1; // Impossible case  
  64.             }  
  65.             min_incoming[root] = 0;  
  66.             pre[root] = root; // This need to set up, or can cause infinite loop  
  67.             int cnt_node = 0;  
  68.             for (int i = 0; i < nv; i++)  
  69.             {  
  70.                   dmst += min_incoming[i];  
  71.                   if (vis[i] == -1)  
  72.                   {  
  73.                         int v = i;  
  74.                         while (vis[v] == -1)  
  75.                         {  
  76.                               vis[v] = i;  
  77.                               v = pre[v];  // climbing up  
  78.                         }  
  79.                         if (v == root or vis[v] != i) continue;  
  80.                         cycle_id[v] = cnt_node; // new cycle, put all the member in same id  
  81.                         for (int u = pre[v]; u != v; u = pre[u]) cycle_id[u] = cnt_node;  
  82.                         cnt_node++;  
  83.                   }  
  84.             }  
  85.             if (cnt_node == 0) break;  
  86.             for (int i = 0; i < nv; i++)  
  87.             {  
  88.                   if (cycle_id[i] == -1) cycle_id[i] = cnt_node++;  
  89.             }  
  90.             for (int i = 0; i < ne; i++)  
  91.             {  
  92.                   int tmp = tedges[i].v;  
  93.                   tedges[i].u = cycle_id[ tedges[i].u ];  
  94.                   tedges[i].v = cycle_id[ tedges[i].v ];  
  95.                   if (tedges[i].u != tedges[i].v) tedges[i].w -= min_incoming[tmp];  
  96.             }  
  97.             nv = cnt_node;  
  98.             root = cycle_id[root];  
  99.       }  
  100.       return dmst;  
  101. }  
  102.   
  103.   
  104. signed main()  
  105. {  
  106.       ios_base::sync_with_stdio(false);  
  107.       cin.tie(nullptr);  
  108.   
  109.       #ifndef ONLINE_JUDGE  
  110.             freopen("in.txt""r", stdin);  
  111.       #endif // ONLINE_JUDGE  
  112.   
  113.       int tc;  
  114.       cin >> tc;  
  115.       for (int tcase = 1; tcase <= tc; tcase++)  
  116.       {  
  117.             int tnode, tedge;  
  118.             cin >> tnode >> tedge;  
  119.             edges.clear();  
  120.             edges.resize(tedge);  
  121.             for (Edge &x : edges) cin >> x.u >> x.v >> x.w;  
  122.             int dmst = directed_mst(0, tnode, tedge);  
  123.             cout << "Case #" << tcase << ": ";  
  124.             if (dmst == -1) cout << "Possums!" << endl;  
  125.             else cout << dmst << endl;  
  126.       }  
  127. }  

Friday, March 27, 2020

[Codeforces] E. Subset Sums

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : E. Subset Sums
Source            : Codeforces
Category          : Data Structure
Algorithm         : Heavy Light Technique
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. #define ll           long long int   
  6. #define endl         '\n'  
  7.   
  8. static const int maxn = 1e5 + 5;  
  9. static const int maxb = 320;  
  10.   
  11. vector <int> light_set[maxn];  
  12. vector <int> heavy_set[maxb];  
  13. int light_heavy_intersection[maxn][maxb];  
  14. int heavy_heavy_intersection[maxb][maxb];  
  15. int num_ele[maxn];  
  16. int mapper[maxn];  
  17. long long lazy[maxn];  
  18. long long ans_heavy[maxn];  
  19. long long arr[maxn];  
  20.   
  21. signed main()  
  22. {  
  23.     ios_base::sync_with_stdio(false);  
  24.     cin.tie(nullptr);  
  25.       
  26.     int n, m, q;  
  27.     cin >> n >> m >> q;  
  28.     for (int i = 1; i <= n; i++) cin >> arr[i];  
  29.     int light = 0;  
  30.     int heavy = 0;  
  31.     for (int i = 1; i <= m; i++)  
  32.     {  
  33.         cin >> num_ele[i];  
  34.         if (num_ele[i] > maxb)  
  35.         {  
  36.             mapper[i] = ++heavy;  
  37.             long long sum = 0;  
  38.             heavy_set[heavy].resize(num_ele[i]);  
  39.             for (int &x : heavy_set[heavy])   
  40.             {  
  41.                 cin >> x;  
  42.                 sum += arr[x];        
  43.             }  
  44.             sort(heavy_set[heavy].begin(), heavy_set[heavy].end());  
  45.             ans_heavy[heavy] = sum;  
  46.         }  
  47.         else   
  48.         {  
  49.             mapper[i] = ++light;  
  50.             light_set[light].resize(num_ele[i]);  
  51.             for (int &x : light_set[light]) cin >> x;  
  52.             sort(light_set[light].begin(), light_set[light].end());  
  53.         }  
  54.     }  
  55.     auto get = [&](vector <int> &vec, int key)  
  56.     {  
  57.         auto fnd = lower_bound(vec.begin(), vec.end(), key);  
  58.         return fnd != vec.end() && *fnd == key;   
  59.     };  
  60.     for (int lgt = 1; lgt <= light; lgt++)  
  61.     {  
  62.         for (int x : light_set[lgt])  
  63.         {  
  64.             for (int hvy = 1; hvy <= heavy; hvy++)   
  65.                 light_heavy_intersection[lgt][hvy] += get(heavy_set[hvy], x);  
  66.         }  
  67.     }  
  68.     for (int hvy = 1; hvy <= heavy; hvy++)  
  69.     {  
  70.         for (int x : heavy_set[hvy])  
  71.         {  
  72.             for (int i = 1; i <= heavy; i++) if (i != hvy)  
  73.                 heavy_heavy_intersection[hvy][i] += get(heavy_set[i], x);    
  74.         }  
  75.     }  
  76.     while (q--)  
  77.     {  
  78.         char type;  
  79.         cin >> type;  
  80.         if (type == '?')  
  81.         {  
  82.             int x;  
  83.             cin >> x;  
  84.             if (num_ele[x] > maxb)  
  85.             {  
  86.                 int hvy = mapper[x];  
  87.                 long long res = ans_heavy[hvy] + 1LL * num_ele[x] * lazy[hvy];  
  88.                 for (int i = 1; i <= heavy; i++) if (hvy != i)  
  89.                     res += heavy_heavy_intersection[hvy][i] * lazy[i];  
  90.                 cout << res << endl;  
  91.             }  
  92.             else  
  93.             {  
  94.                 int lgt = mapper[x];  
  95.                 long long res = 0;  
  96.                 for (int p : light_set[lgt]) res += arr[p];  
  97.                 for (int z = 1; z <= heavy; z++) res += (light_heavy_intersection[lgt][z] * lazy[z]);  
  98.                 cout << res << endl;  
  99.             }  
  100.         }  
  101.         else   
  102.         {  
  103.             int x;  
  104.             long long val;  
  105.             cin >> x >> val;  
  106.             if (num_ele[x] > maxb)   
  107.             {  
  108.                 int hvy = mapper[x];  
  109.                 lazy[hvy] += val;  
  110.             }  
  111.             else   
  112.             {  
  113.                 int lgt = mapper[x];  
  114.                 for (int p : light_set[lgt]) arr[p] += val;  
  115.                 for (int hvy = 1; hvy <= heavy; hvy++) ans_heavy[hvy] += (light_heavy_intersection[lgt][hvy] * val);  
  116.             }  
  117.         }  
  118.     }  
  119. }