Tuesday, September 10, 2019

[Codeforces] E. Build String

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : E. Build String
Source            : Codeforces
Category          : Graph Theory
Algorithm         : Min Cost Max Flow
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. static const int maxn = 100 + 5;  
  6. static const int inf = 500 + 5;  
  7.   
  8. struct Edge  
  9. {  
  10.       int to;  
  11.       int flow;  
  12.       int cap;  
  13.       int cost;  
  14.       int rev;  
  15.       Edge(int to = 0, int flow = 0, int cap = 0, int cost = 0, int rev = 0)  
  16.             : to(to)  
  17.             , flow(flow)  
  18.             , cap(cap)  
  19.             , cost(cost)  
  20.             , rev(rev) {}  
  21. };  
  22.   
  23. struct MinCostMaxFlow  
  24. {  
  25.       int nodes;  
  26.       vector <int> prio;  
  27.       vector <int> curflow;  
  28.       vector <int> prevEdge;  
  29.       vector <int> prevnode;  
  30.       vector <int> q;  
  31.       vector <int> pot;  
  32.       vector <bool> inqueue;  
  33.       vector< vector<Edge> > graph;  
  34.   
  35.       MinCostMaxFlow() {}  
  36.       MinCostMaxFlow(int n)  
  37.             : nodes(n)  
  38.             , prio(n, 0)  
  39.             , curflow(n, 0)  
  40.             , prevEdge(n, 0)  
  41.             , prevnode(n, 0)  
  42.             , q(n, 0)  
  43.             , pot(n, 0)  
  44.             , inqueue(n, 0)  
  45.             , graph(n) {}  
  46.   
  47.       void addEdge(int source, int to, int capacity, int cost)  
  48.       {  
  49.             Edge a = {to, 0, capacity, cost, (int)graph[to].size()};  
  50.             Edge b = {source, 0, 0, -cost, (int)graph[source].size()};  
  51.             graph[source].push_back(a);  
  52.             graph[to].push_back(b);  
  53.       }  
  54.       void bellman_ford(int source, vector<int> &dist)  
  55.       {  
  56.             fill(dist.begin(), dist.end(), INT_MAX);  
  57.             dist[source] = 0;  
  58.             int qt=0;  
  59.             q[qt++] = source;  
  60.             for(int qh = 0;(qh-qt) % nodes != 0; qh++)  
  61.             {  
  62.                   int u = q[qh % nodes];  
  63.                   inqueue[u] = false;  
  64.                   for(auto &e : graph[u])  
  65.                   {  
  66.                         if(e.flow >= e.cap) continue;  
  67.                         int v = e.to;  
  68.                         int newDist = dist[u] + e.cost;  
  69.                         if(dist[v] > newDist)  
  70.                         {  
  71.                               dist[v] = newDist;  
  72.                               if(!inqueue[v])  
  73.                               {  
  74.                                     inqueue[v] = true;  
  75.                                     q[qt++ % nodes] = v;  
  76.                               }  
  77.                         }  
  78.                   }  
  79.             }  
  80.       }  
  81.       pair<intint> minCostFlow(int source, int dest, int maxflow)  
  82.       {  
  83.             bellman_ford(source, pot);  
  84.             int flow = 0;  
  85.             int flow_cost = 0;  
  86.             while(flow < maxflow)  
  87.             {  
  88.                   priority_queue< pair<intint>, vector< pair<intint> >, greater< pair<intint> > > q;  
  89.                   q.push({0, source});  
  90.                   fill(prio.begin(), prio.end(), INT_MAX);  
  91.                   prio[source] = 0;  
  92.                   curflow[source] = INT_MAX;  
  93.                   while(!q.empty())  
  94.                   {  
  95.                         int d = q.top().first;  
  96.                         int u = q.top().second;  
  97.                         q.pop();  
  98.                         if(d != prio[u]) continue;  
  99.                         for(int i = 0; i < graph[u].size(); i++)  
  100.                         {  
  101.                               Edge &e=graph[u][i];  
  102.                               int v = e.to;  
  103.                               if(e.flow >= e.cap) continue;  
  104.                               int newPrio = prio[u] + e.cost + pot[u] - pot[v];  
  105.                               if(prio[v] > newPrio)  
  106.                               {  
  107.                                     prio[v] = newPrio;  
  108.                                     q.push({newPrio, v});  
  109.                                     prevnode[v] = u;  
  110.                                     prevEdge[v] = i;  
  111.                                     curflow[v] = min(curflow[u], e.cap - e.flow);  
  112.                               }  
  113.                         }  
  114.                   }  
  115.                   if(prio[dest] == INT_MAX) break;  
  116.                   for(int i = 0;i < nodes; i++) pot[i] += prio[i];  
  117.                   int df = min(curflow[dest], maxflow - flow);  
  118.                   flow += df;  
  119.                   for(int v = dest; v!= source; v = prevnode[v])  
  120.                   {  
  121.                         Edge &e = graph[ prevnode[v] ][ prevEdge[v] ];  
  122.                         e.flow += df;  
  123.                         graph[v][e.rev].flow -= df;  
  124.                         flow_cost += df * e.cost;  
  125.                   }  
  126.             }  
  127.             return {flow, flow_cost};  
  128.       }  
  129. };  
  130.   
  131. string t;  
  132. string arr[maxn];  
  133. int cap[maxn];  
  134. map <charint> reqd;  
  135. map <charint> pos;  
  136.   
  137. int main()  
  138. {  
  139.       ios_base::sync_with_stdio(false);  
  140.       cin.tie(nullptr);  
  141.       cout.tie(nullptr);  
  142.   
  143.       #ifndef ONLINE_JUDGE  
  144.             freopen("in.txt""r", stdin);  
  145.       #endif // ONLINE_JUDGE  
  146.   
  147.       cin >> t;  
  148.       int n;  
  149.       cin >> n;  
  150.       for (char ch : t) ++reqd[ch];  
  151.       int N = t.size();  
  152.       int nodes = n + reqd.size() + 2;  
  153.       MinCostMaxFlow mcmf(nodes);  
  154.       int ptr = 0;  
  155.       int src = 0;  
  156.       int sink = n + reqd.size() + 1;  
  157.       for (auto it : reqd)  
  158.       {  
  159.             pos[it.first] = ++ptr;  
  160.             mcmf.addEdge(n + ptr, sink, it.second, 0);  
  161.       }  
  162.       for (int i = 1; i <= n; i++)  
  163.       {  
  164.             cin >> arr[i] >> cap[i];  
  165.             mcmf.addEdge(src, i, cap[i], 0);  
  166.             map <charint> cur;  
  167.             for (char ch : arr[i]) ++cur[ch];  
  168.             for (auto it : cur)  
  169.             {  
  170.                   if (reqd.find(it.first) == reqd.end()) continue;  
  171.                   mcmf.addEdge(i, n + pos[it.first], it.second, i);  
  172.             }  
  173.       }  
  174.       pair <intint> res = mcmf.minCostFlow(src, sink, inf);  
  175.       if (res.first != N) res.second = -1;  
  176.       cout << res.second;  
  177. }  

No comments:

Post a Comment

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