Cod sursa(job #2955072)

Utilizator smunteanuMunteanu Stefan Catalin smunteanu Data 16 decembrie 2022 01:58:48
Problema Critice Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.47 kb
#include <bits/stdc++.h>
using namespace std;

const int nmax = 1007;

int n, m;
vector<int> adj[nmax];
int id[nmax][nmax];
int cap[nmax][nmax];
int flow[nmax][nmax];
int par[nmax];
bool give[nmax];
bool take[nmax];

void bfs() {

  memset(par, -1, sizeof(par));

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

  while (!q.empty()) {
    int u = q.front(); q.pop();
    for (int v : adj[u]) {
      if (flow[u][v] > 0 && par[v] == -1) {
        par[v] = u;
        if (v != n) q.push(v);
      }
    }
  }
}

vector<int> solve() {

  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int u, v, f;
    cin >> u >> v >> f;
    adj[u].push_back(v);
    adj[v].push_back(u);
    id[u][v] = id[v][u] = i;
    cap[u][v] = cap[v][u] = f;
    flow[u][v] = flow[v][u] = f;
  }

  for (;;) {

    bfs();

    if (par[n] == -1) break;

    for (int v : adj[n]) {

      if (par[v] == -1 || flow[v][n] == 0) continue;

      int currentFlow = INT_MAX, minCount = 0, lastMin = 0;

      par[n] = v;

      for (int u = n; u != 1; u = par[u]) {
        if (flow[par[u]][u] < currentFlow) currentFlow = flow[par[u]][u], minCount = 0, lastMin = u;
        minCount += flow[par[u]][u] == currentFlow;
      }

      if (currentFlow == 0) continue;

      for (int u = n; u != 1; u = par[u]) {
        flow[par[u]][u] -= currentFlow;
        flow[u][par[u]] += currentFlow;
      }

    }
  }

  queue<int> q;

  q.push(1);
  give[1] = true;
  while (!q.empty()) {
    int u = q.front(); q.pop();
    for (int v : adj[u]) {
      if (!give[v] && flow[u][v] > 0) {
        give[v] = true;
        q.push(v);
      }
    }
  }

  q.push(n);
  take[n] = true;
  while (!q.empty()) {
    int u = q.front(); q.pop();
    for (int v : adj[u]) {
      if (!take[v] && flow[v][u] > 0) {
        take[v] = true;
        q.push(v);
      }
    }
  }

  vector<int> result;

  for (int i = 1; i <= n; i++) {
    for (int j : adj[i]) {
      if (give[i] && take[j] && !give[j] && !take[i]) {
        result.push_back(id[i][j]);
      }
    }
  }

  sort(result.begin(), result.end());

  return result;

}

int main() {
  
  #ifdef LOCAL
  freopen("file.in", "r", stdin);
  #else
  freopen("critice.in", "r", stdin);
  freopen("critice.out", "w", stdout);
  #endif

  ios_base::sync_with_stdio(false), cin.tie(NULL);

  vector<int> result = solve();
  cout << result.size() << '\n';
  for (int i : result) cout << i << '\n';

}