Cod sursa(job #2237863)

Utilizator caesar2001Stoica Alexandru caesar2001 Data 3 septembrie 2018 16:54:55
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.93 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

int const NMAX = 10000;
int const MMAX = 100000;
int const inf = 1000000000;

#define MIN(a , b) ((a < b) ? a : b)
#define MAX(a , b) ((a < b) ? b : a)

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

vector < Edge > g[5 + NMAX];

void addEdge(int from , int to , int cap , int index){
  g[from].push_back({to , g[to].size() , cap , 0, index });
  g[to].push_back({from , g[from].size() - 1 , cap , 0 , index} );
}
int level[5 + NMAX];
int n;

bool bfs(){
  queue< int > q;

  for(int i = 1 ; i <= n ;i++)
    level[i] = 0;
  level[1] = 1;
  q.push(1);
  while(0 < q.size()){
    int node = q.front();
    q.pop();
    for(int h = 0 ; h < g[node].size() ;h++){
      Edge e = g[node][h];
      if(e.flow < e.cap && level[e.to] == 0){
        level[e.to] = level[node] + 1;
        q.push(e.to);
      }
    }
  }
  return 0 < level[n];
}

int rem[5 + NMAX];
int dfs(int node , int deltaflow){
  if(node == n)
    return deltaflow;

  for(int &h = rem[node] ; h < g[node].size() ;h++){
    Edge &e = g[node][h];
    if(level[node] + 1 == level[e.to] && e.flow < e.cap){
      int delta = dfs(e.to ,MIN(deltaflow ,e.cap - e.flow));
      if(0 < delta){
        e.flow += delta;
        g[e.to][e.rev].flow -= delta;
        return delta;
      }
    }
  }
  return 0;
}
int maxflow(){
  int flowsum = 0;
  while(bfs()){
    for(int i = 1 ; i <= n ;i++)
      rem[i] = 0;

    int deltaflow = 0;

    bool ok = 0;
    do{
      deltaflow = dfs(1 , inf);
      flowsum += deltaflow;

    } while(0 < deltaflow);
  }
  return flowsum;
}
int marker[5 + NMAX];

void mark(int node ,int val ){
  queue < int > q;
  q.push(node);
  int seen[5 + NMAX] = {0};
  while(0 < q.size()){
    int node = q.front();
    marker[node] |= val;
    q.pop();
    for(int h = 0 ; h < g[node].size() ;h++){
      Edge &e = g[node][h];
      if(e.flow < e.cap && g[e.to][e.rev].flow < e.cap && seen[e.to] == 0){
        seen[e.to] = 1;
        q.push(e.to);
      }
    }
  }
}
vector<pair<int , int >> edges;

int main()
{
  int m;
  in >> n >> m;
  edges.push_back({0 , 0});
  for(int i = 1 ; i <= m ;i++){
    int from , to , cap;
    in >> from >> to >> cap;
    addEdge(from , to , cap , i);
    edges.push_back({from , to});
  }
  maxflow();
  mark(1 , 1);
  mark(n , 2);
  int result = 0;
  for(int i = 1 ; i <= m;i++)
    if((marker[edges[i].first] == 1 && marker[edges[i].second] == 2) || (marker[edges[i].first] == 2 && marker[edges[i].second] == 1))
      result++;
  out << result << '\n';
  for(int i = 1 ; i <= m ;i++){
    if((marker[edges[i].first] == 1 && marker[edges[i].second] == 2) || (marker[edges[i].first] == 2 && marker[edges[i].second] == 1))
      out << i << '\n';
  }
  return 0;
}