Cod sursa(job #2695646)

Utilizator Stefan_RaduStefan Radu Stefan_Radu Data 14 ianuarie 2021 02:15:40
Problema Critice Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.54 kb
// By Stefan Radu

#include <bits/stdc++.h>

using namespace std;

#define sz(x) (int)(x).size()

typedef pair < int, int > pii;
typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef unsigned long long ull;

int cap[1000][1000];
int flow[1000][1000];

struct Edge {
  int node, ind;
};

vector < int > lvl;
vector < vector < Edge > > gr;

const int INF = 2e9;

bool bfs(int n) {

  fill(lvl.begin(), lvl.end(), 0);

  queue < int > q;
  q.push(0);
  lvl[0] = 1;

  while (!q.empty()) {

    int curr = q.front();
    q.pop();

    if (curr == n) return true;

    for (auto &nei : gr[curr]) {
      if (lvl[nei.node]) continue;
      if (flow[curr][nei.node] < cap[curr][nei.node]) {
        lvl[nei.node] = lvl[curr] + 1;
        q.push(nei.node);
      }
    }
  }

  return false;
}


int dfs(int node, int &n, int toPush) {

  if (node == n) return toPush;

  int ret = 0;
  for (auto &nei : gr[node]) {
    if (lvl[nei.node] != lvl[node] + 1) continue;
    if (flow[node][nei.node] < cap[node][nei.node]) {

      int push = min(toPush, cap[node][nei.node] - flow[node][nei.node]);
      int pushed = dfs(nei.node, n, push);

      ret += pushed;
      toPush -= pushed;
      flow[node][nei.node] += pushed;
      flow[nei.node][node] -= pushed;

      if (toPush == 0) break;
    }
  }

  return ret;
}

int main() {

  ifstream fin("critice.in");
  int n, m; fin >> n >> m;

  gr.resize(n);
  lvl.resize(n);

  for (int i = 1; i <= m; ++ i) {
    int a, b, c;
    fin >> a >> b >> c;
    -- a; -- b;
    cap[a][b] = cap[b][a] = c;
    gr[a].push_back({b, i});
    gr[b].push_back({a, i});
  }

  n --;
  int ret = 0;
  while (bfs(n)) {
    ret += dfs(0, n, INF);
  }

  vector < int > marked(n + 1);
  queue < int > q;

  q.push(0);
  marked[0] = 1;
  while (!q.empty()) {
    int curr = q.front();
    q.pop();

    for (auto &nei : gr[curr]) {
      if (marked[nei.node]) continue;
      if (abs(flow[curr][nei.node]) < max(cap[curr][nei.node], cap[nei.node][curr])) {
        marked[nei.node] = 1;
        q.push(nei.node);
      }
    }
  }

  q.push(n);
  marked[n] = 2;

  set < int > ans;

  while (!q.empty()) {
    int curr = q.front();
    q.pop();

    for (auto &nei : gr[curr]) {
      if (marked[nei.node]) {
        if (marked[nei.node] == 1) ans.insert(nei.ind);
        continue;
      }
      if (abs(flow[curr][nei.node]) < max(cap[curr][nei.node], cap[nei.node][curr])) {
        marked[nei.node] = 2;
        q.push(nei.node);
      }
    }
  }

  ofstream fout("critice.out");
  fout << sz(ans) << '\n';
  for (int x : ans) fout << x << '\n';
}