chang2394

Untitled

Sep 30th, 2014
252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.72 KB | None | 0 0
  1. #include <cmath>
  2. #include <vector>
  3. #include <iostream>
  4. #include <queue>
  5. #include <cstring>
  6.  
  7. using namespace std;
  8.  
  9. typedef long long LL;
  10.  
  11. struct Edge {
  12.   int from, to, cap, flow, index;
  13.   Edge(int from, int to, int cap, int flow, int index) :
  14.     from(from), to(to), cap(cap), flow(flow), index(index) {}
  15. };
  16.  
  17. struct PushRelabel {
  18.   int N;
  19.   vector<vector<Edge> > G;
  20.   vector<LL> excess;
  21.   vector<int> dist, active, count;
  22.   queue<int> Q;
  23.  
  24.   PushRelabel(int N) : N(N), G(N), excess(N), dist(N), active(N), count(2*N) {}
  25.  
  26.   void AddEdge(int from, int to, int cap) {
  27.     G[from].push_back(Edge(from, to, cap, 0, G[to].size()));
  28.     if (from == to) G[from].back().index++;
  29.     G[to].push_back(Edge(to, from, 0, 0, G[from].size() - 1));
  30.   }
  31.  
  32.   void Enqueue(int v) {
  33.     if (!active[v] && excess[v] > 0) { active[v] = true; Q.push(v); }
  34.   }
  35.  
  36.   void Push(Edge &e) {
  37.     int amt = int(min(excess[e.from], LL(e.cap - e.flow)));
  38.     if (dist[e.from] <= dist[e.to] || amt == 0) return;
  39.     e.flow += amt;
  40.     G[e.to][e.index].flow -= amt;
  41.     excess[e.to] += amt;
  42.     excess[e.from] -= amt;
  43.     Enqueue(e.to);
  44.   }
  45.  
  46.   void Gap(int k) {
  47.     for (int v = 0; v < N; v++) {
  48.       if (dist[v] < k) continue;
  49.       count[dist[v]]--;
  50.       dist[v] = max(dist[v], N+1);
  51.       count[dist[v]]++;
  52.       Enqueue(v);
  53.     }
  54.   }
  55.  
  56.   void Relabel(int v) {
  57.     count[dist[v]]--;
  58.     dist[v] = 2*N;
  59.     for (int i = 0; i < G[v].size(); i++)
  60.       if (G[v][i].cap - G[v][i].flow > 0)
  61.     dist[v] = min(dist[v], dist[G[v][i].to] + 1);
  62.     count[dist[v]]++;
  63.     Enqueue(v);
  64.   }
  65.  
  66.   void Discharge(int v) {
  67.     for (int i = 0; excess[v] > 0 && i < G[v].size(); i++) Push(G[v][i]);
  68.     if (excess[v] > 0) {
  69.       if (count[dist[v]] == 1)
  70.     Gap(dist[v]);
  71.       else
  72.     Relabel(v);
  73.     }
  74.   }
  75.  
  76.   LL GetMaxFlow(int s, int t) {
  77.     count[0] = N-1;
  78.     count[N] = 1;
  79.     dist[s] = N;
  80.     active[s] = active[t] = true;
  81.     for (int i = 0; i < G[s].size(); i++) {
  82.       excess[s] += G[s][i].cap;
  83.       Push(G[s][i]);
  84.     }
  85.  
  86.     while (!Q.empty()) {
  87.       int v = Q.front();
  88.       Q.pop();
  89.       active[v] = false;
  90.       Discharge(v);
  91.     }
  92.  
  93.     LL totflow = 0;
  94.     for (int i = 0; i < G[s].size(); i++) totflow += G[s][i].flow;
  95.     return totflow;
  96.   }
  97. };
  98.  
  99. void solve(){
  100.     int n,m,a,b,wt;
  101.     cin >> n >> m;
  102.  
  103.     PushRelabel gg(n);
  104.     for(int i = 0; i < m; ++i){
  105.         cin >> a >> b >> wt;
  106.         gg.AddEdge(a-1,b-1,wt);
  107.     }
  108.  
  109.     int cases;
  110.     cin >> cases;
  111.     while(cases--){
  112.         int s,t;
  113.         cin >> s >> t;
  114.         PushRelabel tmp = gg;
  115.         LL ans = tmp.GetMaxFlow(s-1,t-1);
  116.         cout << ans << endl;
  117.     }
  118. }
  119.  
  120. int main()
  121. {
  122.     ios_base::sync_with_stdio(false);
  123.     solve();
  124.     return 0;
  125. }
Advertisement
Add Comment
Please, Sign In to add comment