Cod sursa(job #3262969)

Utilizator TeodorLuchianovTeo Luchianov TeodorLuchianov Data 12 decembrie 2024 15:33:58
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.29 kb
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

ifstream in("maxflow.in");
ofstream out("maxflow.out");

typedef long long ll;

int const INF = 1e9+7;

struct Edge{
  int from;
  int to;
  ll flow;
};

int const MMAX = 5000;
Edge edges[1 + 2 * MMAX];

int const NMAX = 1000;
vector <int> g[1 + NMAX];
int edge_ind[1 + NMAX];
int dist[1 + NMAX];

void BFS(int start, int n) {
  for(int i = 1;i <= n;i++) {
    dist[i] = INF;
  }
  queue <int> q;
  dist[start] = 0;
  q.push(start);
  while(!q.empty()) {
    int from = q.front();
    q.pop();
    for(int i = 0;i < g[from].size();i++) {
      int to = edges[g[from][i]].to;
      ll flow = edges[g[from][i]].flow;
      if(flow != 0 && (dist[from] + 1 < dist[to])) {
        dist[to] = dist[from] + 1;
        q.push(to);
      }
    }
  }
  //for(int i = 1;i <= n;i++) {
  //  cerr << dist[i] << ' ';
  //}
  //cerr << '\n';
}

int DFS(int node, int minflow, int sink) {
  if(node == sink) {
    return minflow;
  }else {
    ll pushed = 0;
    while(minflow > 0 && edge_ind[node] < g[node].size()) {
      int i = edge_ind[node];
      edge_ind[node]++;
      int to = edges[g[node][i]].to;
      ll flow = edges[g[node][i]].flow;
      //cerr << node << ' ' << to << ' ' << flow << '\n';
      if(flow != 0 && (dist[node] < dist[to])) {
        ll temp = DFS(to, min(minflow - pushed, flow), sink);
        if(pushed + temp <= minflow) {
          pushed += temp;
          edges[g[node][i]].flow -= temp;
          edges[g[node][i] ^ 1].flow += temp;
        }
      }
    }
    return pushed;
  }
  return 0;
}

ll computeDinic(int source, int sink, int n) {
  ll ans = 0;
  bool isGood = true;
  while(isGood) {
    BFS(source, n);
    for(int i = 1;i <= n;i++) {
      edge_ind[i] = 0;
    }
    ll pushed = DFS(source, INF, sink);
    ans += pushed;
    //cerr << pushed << '\n';
    if(pushed == 0) {
      isGood = false;
    }
  }
  return ans;
}

int main() {

  int n, m;
  in >> n >> m;
  for(int i = 1;i <= m;i++) {
    int a, b, flow;
    in >> a >> b >> flow;
    edges[2 * i - 2] = {a, b, flow};
    edges[2 * i - 1] = {b, a, 0};
    g[a].push_back(2 * i - 2);
    g[b].push_back(2 * i - 1);
  }
  out << computeDinic(1, n, n);
  return 0;
}