Cod sursa(job #2021709)

Utilizator GoogalAbabei Daniel Googal Data 14 septembrie 2017 13:26:24
Problema Critice Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.54 kb
#include <fstream>
#include <iostream>
#include <algorithm>
#include <climits>
#include <bitset>
#include <vector>
#include <queue>

using namespace std;

const int nmax = 1000;
const int DIM = 1000000;

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

struct Edge {
  int ind;
  int to;
  int rev;
  int flow;
  int cap;
};

vector< Edge > g[1 + nmax];
vector < int > ig[1 + nmax];
vector < int > sol;
bitset < 1 + nmax > vis;
int n, m, src, dest, pos;
int cap[1 + nmax][1 + nmax];
char buff[DIM];

void rno(int &no){
  no = 0;
  while(!isdigit(buff[pos])){
    if(++pos == DIM){
      in.read(buff, DIM);
      pos = 0;
    }
  }

  while(isdigit(buff[pos])){
    no = (no * 10) + (buff[pos] - '0');
    if(++pos == DIM){
      in.read(buff, DIM);
      pos = 0;
    }
  }
}

void addedge(int i, int j, int c, int ind) {
  Edge direct  = {ind, j, g[j].size(), 0, c};
  Edge inverse = {ind, i, g[i].size(), 0, c};
  g[i].push_back(direct);
  g[j].push_back(inverse);
}


void read() {
  in.read(buff, DIM);
  //in >> n >> m;
  rno(n);
  rno(m);
  src = 1;
  dest = n;
  for(int i = 1; i <= m; i++){
    int x, y, z;
    //in >> x >> y >> z;
    rno(x);
    rno(y);
    rno(z);
    addedge(x, y, z, i);
  }
}

int dist[1 + nmax];

bool bfs() {
  fill(dist + 1, dist + n + 1, -1);
  queue < int > q;
  q.push(src);
  dist[src] = 0;
  while(!q.empty()){
    int from = q.front();
    q.pop();
    for(int i = 0; i < g[from].size(); i++){
      Edge &e = g[from][i];
      int to = e.to;
      if(dist[to] < 0 && e.flow < e.cap){
        dist[to] = dist[from] + 1;
        q.push(to);
      }
    }
  }
  return (0 <= dist[dest]);
}

int rem[1 + nmax];

int dfs(int from, int deltaflow) {
  if(from == dest)
    return deltaflow;
  else {
    for(int i = rem[from]; i < g[from].size(); i++) {
      Edge &e = g[from][i];
      if(dist[e.to] == dist[from] + 1) {
        int addflow = dfs(e.to, min(deltaflow, e.cap - e.flow));
        if(0 < addflow) {
          e.flow += addflow;
          g[e.to][e.rev].flow -= addflow;
          rem[from] = i;
          return addflow;
        }
      }
    }
    return 0;
  }
}

int maxflow() {
  int result = 0;
  while(bfs()) {
    fill(rem + 1, rem + n + 1, 0);
    while(int deltaflow = dfs(src, INT_MAX)) {
      result += deltaflow;
    }
  }
  return result;
}

bool finalbfs(int node) {
  queue < int > q;

  q.push(node);
  if(node == n)
    return 1;
  while(!q.empty()) {
    int from = q.front();
    q.pop();
    for(int i = 0; i < ig[from].size(); i++) {
      int to = ig[from][i];
      if(to == n)
        return 1;
      else
        q.push(to);
    }
  }
  return 0;
}

int main() {
  read();
  maxflow();

  for(int i = 1; i <= n; i++) {
    for(int j = 0; j < g[i].size(); j++) {
      Edge &e = g[i][j];
      if(e.flow < e.cap)
        ig[i].push_back(e.to);
    }
  }

  queue < int > q;
  q.push(1);
  vis[1] = 1;
  while(!q.empty()) {
    int from = q.front();
    q.pop();
    for(int i = 0; i < g[from].size(); i++) {
      Edge &e = g[from][i];
      if(vis[e.to] == 0 && e.flow == e.cap && 0 < e.cap) {
        if(finalbfs(e.to) == true)
          sol.push_back(e.ind);
      } else if(vis[e.to] == 0 && e.flow < e.cap) {
        vis[e.to] = 1;
        q.push(e.to);
      }
    }
  }

  sort(sol.begin(), sol.end());
  out << sol.size() << '\n';

  for(int i = 0; i < sol.size(); i++)
    out << sol[i] << '\n';

  in.close();
  out.close();
  return 0;
}