Tuesday, January 22, 2019

[toph.co] Budget Travel

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : Budget Travel
Source            : toph.co
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 = 1e3 + 5;  
  6. //Works for negative costs, but does not work for negative cycles  
  7. //Complexity: O(min(E^2 *V log V, E logV * flow))  
  8.   
  9. struct edge  
  10. {  
  11.     int to, flow, cap, cost, rev;  
  12.     edge(int to = 0, int flow = 0, int cap = 0, int cost = 0, int rev = 0) :  
  13.           to(to), flow(flow), cap(cap), cost(cost), rev(rev) {}  
  14. };  
  15.   
  16. struct MinCostMaxFlow  
  17. {  
  18.     int nodes;  
  19.     vector <int> prio, curflow, prevedge, prevnode, q, pot;  
  20.     vector <bool> inqueue;  
  21.     vector< vector<edge> > graph;  
  22.   
  23.     MinCostMaxFlow() {}  
  24.   
  25.     MinCostMaxFlow(int n) :  
  26.           nodes(n), prio(n, 0), curflow(n, 0), prevedge(n, 0),  
  27.           prevnode(n, 0), q(n, 0), pot(n, 0), inqueue(n, 0), graph(n) {}  
  28.   
  29.     void addEdge(int source, int to, int capacity, int cost)  
  30.     {  
  31.         edge a = {to, 0, capacity, cost, (int)graph[to].size()};  
  32.         edge b = {source, 0, 0, -cost, (int)graph[source].size()};  
  33.         graph[source].push_back(a);  
  34.         graph[to].push_back(b);  
  35.     }  
  36.   
  37.     void bellman_ford(int source, vector<int> &dist)  
  38.     {  
  39.         fill(dist.begin(), dist.end(), INT_MAX);  
  40.         dist[source] = 0;  
  41.         int qt=0;  
  42.         q[qt++] = source;  
  43.         for(int qh = 0;(qh-qt) % nodes != 0; qh++)  
  44.         {  
  45.             int u = q[qh % nodes];  
  46.             inqueue[u] = false;  
  47.             for(auto &e : graph[u])  
  48.             {  
  49.                 if(e.flow >= e.cap) continue;  
  50.                 int v = e.to;  
  51.                 int newDist = dist[u] + e.cost;  
  52.                 if(dist[v] > newDist)  
  53.                 {  
  54.                     dist[v] = newDist;  
  55.                     if(!inqueue[v])  
  56.                     {  
  57.                         inqueue[v] = true;  
  58.                         q[qt++ % nodes] = v;  
  59.                     }  
  60.                 }  
  61.             }  
  62.         }  
  63.     }  
  64.   
  65.     pair<intint> minCostFlow(int source, int dest, int maxflow)  
  66.     {  
  67.         bellman_ford(source, pot);  
  68.         int flow = 0;  
  69.         int flow_cost = 0;  
  70.         while(flow < maxflow)  
  71.         {  
  72.             priority_queue< pair<intint>, vector< pair<intint> >, greater< pair<intint> > > q;  
  73.             q.push({0, source});  
  74.             fill(prio.begin(), prio.end(), INT_MAX);  
  75.             prio[source] = 0;  
  76.             curflow[source] = INT_MAX;  
  77.             while(!q.empty())  
  78.             {  
  79.                 int d = q.top().first;  
  80.                 int u = q.top().second;  
  81.                 q.pop();  
  82.                 if(d != prio[u]) continue;  
  83.                 for(int i = 0; i < graph[u].size(); i++)  
  84.                 {  
  85.                     edge &e=graph[u][i];  
  86.                     int v = e.to;  
  87.                     if(e.flow >= e.cap) continue;  
  88.                     int newPrio = prio[u] + e.cost + pot[u] - pot[v];  
  89.                     if(prio[v] > newPrio)  
  90.                     {  
  91.                         prio[v] = newPrio;  
  92.                         q.push({newPrio, v});  
  93.                         prevnode[v] = u;  
  94.                         prevedge[v] = i;  
  95.                         curflow[v] = min(curflow[u], e.cap - e.flow);  
  96.                     }  
  97.                 }  
  98.             }  
  99.             if(prio[dest] == INT_MAX) break;  
  100.             for(int i = 0;i < nodes; i++) pot[i] += prio[i];  
  101.             int df = min(curflow[dest], maxflow - flow);  
  102.             flow += df;  
  103.             for(int v = dest; v!= source; v = prevnode[v])  
  104.             {  
  105.                 edge &e = graph[ prevnode[v] ][ prevedge[v] ];  
  106.                 e.flow += df;  
  107.                 graph[v][e.rev].flow -= df;  
  108.                 flow_cost += df * e.cost;  
  109.             }  
  110.         }  
  111.         return {flow, flow_cost};  
  112.     }  
  113. };  
  114.   
  115. int desCost[maxn];  
  116.   
  117. int main()  
  118. {  
  119.       //freopen("in.txt", "r", stdin);  
  120.   
  121.       int N, D;  
  122.       scanf("%d %d", &D, &N);  
  123.       MinCostMaxFlow mcmf(N+D+2);  
  124.       for (int i = 1; i <= D; i++) scanf("%d", &desCost[i+N]);  
  125.       for (int u = 1; u <= N; u++)  
  126.       {  
  127.           int prefers;  
  128.           scanf("%d", &prefers);  
  129.           for (int i = 1; i <= prefers; i++)  
  130.           {  
  131.                 int v;  
  132.                 scanf("%d", &v);  
  133.                 v += N;  
  134.                 mcmf.addEdge(u, v, 1, desCost[v]);  
  135.                 mcmf.addEdge(v, u, 1, desCost[v]);  
  136.           }  
  137.       }  
  138.       if (D < N)  
  139.       {  
  140.             puts("-1");  
  141.             exit(0);  
  142.       }  
  143.       int S = 0;  
  144.       int T = N + D + 1;  
  145.       for (int v = 1; v <= N; v++)  
  146.       {  
  147.             mcmf.addEdge(S, v, 1, 0);  
  148.             mcmf.addEdge(v, S, 1, 0);  
  149.       }  
  150.       for (int u = N+1; u <= N+D; u++)  
  151.       {  
  152.             mcmf.addEdge(u, T, 1, 0);  
  153.             mcmf.addEdge(T, u, 1, 0);  
  154.       }  
  155.       pair <intint> res = mcmf.minCostFlow(S, T, N);  
  156.       if (res.first != N) res.second = -1;  
  157.       printf("%d\n", res.second);  
  158. }  

No comments:

Post a Comment

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