Cod sursa(job #2017383)

Utilizator MiricaMateiMirica Matei MiricaMatei Data 31 august 2017 23:54:55
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 kb
#include <cstdio>
#include <cstring>
#include <climits>
#include <vector>
#include <queue>
#include <algorithm>

const int MAX_N = 1000;
const int MAX_M = 10000;

struct Edge {
  int u, v;
};

std::vector<int> neighbours[1 + MAX_N];
std::vector<Edge> e;

int cr[1 + MAX_N][1 + MAX_N];
int ind[1 + MAX_N][1 + MAX_N];
int in[1 + MAX_N][1 + MAX_N];
bool visited[1 + MAX_N];
int from[1 + MAX_N];
int ans[1 + MAX_M];
bool viz1[1 + MAX_N];
bool viz2[1 + MAX_N];

bool bfs(int s, int d) {
  memset(visited, 0, sizeof(visited));
  std::queue<int> q;
  q.push(s);
  visited[s] = true;
  from[s] = s;
  while (!q.empty() && !visited[d]) {
    int u = q.front();
    q.pop();
    for (auto v : neighbours[u]) {
      if (!visited[v] && cr[u][v] > 0) {
        q.push(v);
        visited[v] = true;
        from[v] = u;
      }
    }
  }
  return visited[d];
}

void  maxFlow(int s, int d) {
  int answer = 0;
  while (bfs(s, d)) {
    for (auto it : neighbours[d]) {
      int flux = INT_MAX;
      int u = it;
      if (cr[u][d] == 0 || !visited[u])
        continue;
      from[d] = u;
      u = d;
      while (u != s) {
        flux = std::min(flux, cr[from[u]][u]);
        u = from[u];
      }
      u = d;
      while (u != s) {
        cr[from[u]][u] -= flux;
        cr[u][from[u]] += flux;
        u = from[u];
      }
    }
  }
}

void bfs1(int s, bool viz[]) {
  std::queue<int> q;
  q.push(s);
  viz[s] = true;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (auto v : neighbours[u]) {
      if (!viz[v] && cr[u][v] > 0 && cr[v][u] > 0) {
        q.push(v);
        viz[v] = true;
      }
    }
  }
}

int main() {
  freopen("critice.in", "r", stdin);
  freopen("critice.out", "w", stdout);

  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    neighbours[u].push_back(v);
    neighbours[v].push_back(u);
    scanf("%d", &cr[u][v]);
    cr[v][u] = cr[u][v];
    e.push_back({u, v});
  }

  maxFlow(1, n);
  bfs1(1, viz1);
  bfs1(n, viz2);
  int k = 0;
  for (int i = 0; i < m; ++i) {
    if ((viz1[e[i].u] && viz2[e[i].v]) || (viz2[e[i].u] && viz1[e[i].v]))
      ans[++k] = i + 1;
  }

  printf("%d\n", k);
  for (int i = 1; i <= k; ++i)
    printf("%d\n", ans[i]);

  return 0;
}