Advertisement
Ahmed_Negm

Untitled

Nov 5th, 2024
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.67 KB | None | 0 0
  1. struct MCMF{
  2.     struct Edge{
  3.         int from, to, rev;
  4.         ll cost, cap, flow;
  5.  
  6.         Edge(int _from, int _to, ll _cap, ll _cost,int _rev){
  7.             from = _from, to = _to, cap = _cap, cost = _cost, rev = _rev;
  8.             flow = 0;
  9.         }
  10.  
  11.         bool operator < (const Edge &e) const{
  12.             return cost < e.cost;
  13.         }
  14.     };
  15.  
  16.     int n;
  17.     vector<vector<Edge>> adj;
  18.     const ll INF = 1e16;
  19.  
  20.     MCMF(int _n){
  21.         n = _n+2;
  22.         adj = vector<vector<Edge>>(n);
  23.     }
  24.  
  25.     void addEdge(int u,int v,ll cost,ll cap){
  26.         Edge a = Edge(u,v,cap,cost,adj[v].size());
  27.         Edge b = Edge(v,u,0,-cost,adj[u].size());
  28.         adj[u].push_back(a);
  29.         adj[v].push_back(b);
  30.     }
  31.  
  32.     pair<ll,ll> minCostMaxFlow(int s,int t){
  33.         ll maxFlow = 0, cost = 0;
  34.  
  35.         while(true){
  36.             vector<pair<ll,ll>> path = spfa(s,t);
  37.             if(path.empty()) break;
  38.  
  39.             ll newFlow = INF;
  40.             for(auto &it: path){
  41.                 Edge &e = adj[it.first][it.second];
  42.                 newFlow = min(newFlow,e.cap - e.flow);
  43.             }
  44.  
  45.             for(auto&it : path){
  46.                 Edge &e = adj[it.first][it.second];
  47.                 e.flow += newFlow;
  48.                 cost += e.cost * newFlow;
  49.                 adj[e.to][e.rev].flow -= newFlow;
  50.             }
  51.             maxFlow += newFlow;
  52.         }
  53.  
  54.         return {maxFlow,cost};
  55.     }
  56.  
  57.  
  58.     enum visit {unvisited, inqueue, visited};
  59.  
  60.     vector<pair<ll,ll>> spfa(int s,int t){
  61.         vector<int> dist(n,INF),prev(n,-1),from_edge(n),state(n,unvisited);
  62.         queue<int> q;
  63.         dist[s] = 0;
  64.         q.push(s);
  65.  
  66.  
  67.         while(!q.empty()){
  68.             int u = q.front();
  69.             q.pop();
  70.             for(int i = 0; i < adj[u].size(); i++){
  71.                 Edge e = adj[u][i];
  72.                 if(e.flow >= e.cap || dist[e.to] <= dist[u] + e.cost) continue;
  73.  
  74.                 dist[e.to] = dist[u] + e.cost;
  75.                 prev[e.to] = u;
  76.                 from_edge[e.to] = i;
  77.  
  78.                 if(state[e.to] == inqueue) continue;
  79.                 if(state[e.to] == visited || (!q.empty() and dist[q.front()] > dist[e.to])){
  80.                     q.push(e.to);
  81.                 }else{
  82.                     q.push(e.to);
  83.                 }
  84.                 state[e.to] = inqueue;
  85.             }
  86.         }
  87.  
  88.  
  89.         if(dist[t] == INF) return {};
  90.         if(dist[t] > 0) return {};
  91.         vector<pair<ll,ll>> path;
  92.         int cur = t;
  93.         while(cur != s){
  94.             path.push_back({prev[cur],from_edge[cur]});
  95.             cur = prev[cur];
  96.         }
  97.  
  98.  
  99.         reverse(path.begin(),path.end());
  100.         return path;
  101.     }
  102.  
  103. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement