Cod sursa(job #3293472)

Utilizator TeodorLuchianovTeo Luchianov TeodorLuchianov Data 11 aprilie 2025 19:37:22
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.04 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

int const INF = 1e9+7;

struct Edge{
  int to;
  int flow;
};

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

void addEdge(int from, int to, int flow) {
  edges.push_back({to, flow}); 
  edges.push_back({from, 0});
  g[from].push_back(edges.size()-2);
  g[to].push_back(edges.size()-1);
}

void BFS(int start, int n) {
  for(int i = 1;i <= n;i++) { 
    dist[i] = INF;
    edge_ind[i] = 0;
  } 
  queue <int> q;
  q.push(start);
  dist[start] = 0;
  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, flow = edges[g[from][i]].flow;
      if(flow > 0 && dist[from] + 1 < dist[to]) {
	dist[to] = dist[from] + 1;
	q.push(to);
      }
    }
  }
}

void pushEdge(int ind, int flow) {
  edges[ind].flow -= flow;
  edges[ind^1].flow += flow;
}

int computePushed(int node, int minflow, int sink) {
  if(node == sink) {
    return minflow;
  } else {
    int pushed = 0;
    for(int i = edge_ind[node];i < g[node].size();i++) {
      int to = edges[g[node][i]].to, flow = edges[g[node][i]].flow;
      if(flow > 0 && dist[node] + 1 <= dist[to] && dist[to] != INF) {
	int tempPush = computePushed(to, min(minflow - pushed, flow), sink);
        pushed += tempPush;
	pushEdge(g[node][i], tempPush);
	if(pushed == minflow) {
          return pushed;
	}
      }
      edge_ind[node]++;
    }
    return pushed;
  }
}

int computeDinic(int source, int sink, int n) {
  int ans = 0;
  bool canPush = true;
  while(canPush) {
    BFS(source, n);
    canPush = false;
    int pushed = computePushed(source, INF, sink);
    ans += pushed;
    if(pushed > 0) {  
      canPush = true;
    }
  }
  return ans;
}

int main() {

  int n, m;
  in >> n >> m;
  for(int i = 1;i <= m;i++) {
    int a, b, c;
    in >> a >> b >> c;
    addEdge(a, b, c);
  }
  out << computeDinic(1, n, n);
  return 0;
}