Cod sursa(job #2899892)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 9 mai 2022 16:13:37
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.26 kb
/// always:
#include <cstdio>
#include <string>

/// optional:
#include <cassert>
#include <cstring>
#include <iostream>
#include <vector>
#include <iomanip>
#include <algorithm>
#include <queue>

bool home = 1;
using namespace std;

typedef long double ld;
const string TASKNAME="maxflow";

struct Flow {
  const int INF=(int)1e9+7;
  struct Edge {
    int to;
    int cap;

  };
  int n;
  vector<Edge> edges;
  vector<vector<int>> g;
  vector<int> level;
  vector<int> p;

  Flow(int n) :
    n(n),
    edges(n),
    g(n),
    level(n),
    p(n) {
      assert(n>=2);
    }

  void addEdge(int a,int b,int c) {
    assert(0<=a&&a<n);
    assert(0<=b&&b<n);
    g[a].push_back((int)edges.size());
    g[b].push_back((int)edges.size()+1);
    edges.push_back({b, c});
    edges.push_back({a, 0});
  }

  int dfs(int a,int cur) {
    if (cur==0||a==n-1) return cur;
    while (p[a]<(int)g[a].size()) {
      int i=g[a][p[a]++];
      int b=edges[i].to,cap=edges[i].cap;
      if (level[b]==1+level[a]&&cap>0) {
        int x=dfs(b,min(cur,cap));
        if (x>0) {
          p[a]--;
          edges[i].cap-=x;
          edges[i^1].cap+=x;
          return x;
        }
      }
    }
    return 0;
  }

  int get() {

    int sol=0;
    while (1) {
      for (int i=0;i<n;i++) level[i]=-1,p[i]=0;
      level[0]=0;
      queue<int> q;
      q.push(0);
      while (!q.empty()) {
        int a=q.front();
        q.pop();
        for (auto &i:g[a]) {
          if (level[edges[i].to]==-1&&edges[i].cap>0) {
            q.push(edges[i].to);
            level[edges[i].to]=1+level[a];
          }
        }
      }
      if(level[n-1]==-1) break;
      int value;
      while (1) {
        value=dfs(0,INF);
        if (value==0) break;
        sol+=value;
      }
    }
    return sol;
  }
};

signed main() {
#ifdef INFOARENA
  home = 0;
#endif
  ///home=0;
  if(!home) {
    freopen((TASKNAME + ".in").c_str(), "r", stdin);
    freopen((TASKNAME + ".out").c_str(), "w", stdout);
  }else{
    freopen ("I_am_iron_man", "r", stdin);
  }

  int n,m;
  cin>>n>>m;
  Flow flow(n);
  for (int i=1;i<=m;i++) {
    int a,b,c;
    cin>>a>>b>>c;
    flow.addEdge(a-1,b-1,c);
  }
  cout<<flow.get()<<"\n";
}