Cod sursa(job #2937900)

Utilizator andreic06Andrei Calota andreic06 Data 11 noiembrie 2022 12:24:30
Problema Critice Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.14 kb
#include <bits/stdc++.h>

using namespace std;
const int NMAX = 1e3;
const int MMAX = 1e4;
const int NONE = -1;
const int INF = 2e9;

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

int n, m;
struct MaxFlow {
   int flow[1 + NMAX][1 + NMAX], cap[1 + NMAX][1 + NMAX];
   int p[1 + NMAX]; bool vis[1 + NMAX];

   struct define_edge {
      int to, idx;
   }; vector<define_edge> g[1 + NMAX];

   void add_edge (int a, int b, int c, int idx) {
      g[a].push_back ( {b, idx} );
      g[b].push_back ( {a, idx} );
      cap[a][b] = cap[b][a] = c;
      flow[a][b] = flow[b][a] = 0;
   }

   int source, sink;
   bool bfs () {
      for ( int node = 1; node <= NMAX; node ++ )
         vis[node] = false;
      for ( int node = 1; node <= NMAX; node ++ )
         p[node] = NONE;

      queue<int> q; q.push (source);
      p[source] = NONE; vis[source] = true;
      while ( !q.empty () ) {
         int node = q.front (); q.pop ();
         for ( define_edge obj : g[node] ) {
            if ( !vis[obj.to] && flow[node][obj.to] < cap[node][obj.to] ) {
              p[obj.to] = node;
              vis[obj.to] = true;
              q.push ( obj.to );

              if ( obj.to == sink )
                return true;
            }
         }
      }
      return false;
   }

   void getFlow () {
      while ( bfs () ) {
         for ( define_edge obj : g[sink] ) {
            if ( vis[obj.to] && flow[obj.to][sink] < cap[obj.to][sink] ) {
              p[sink] = obj.to;

              int node = sink; int addFlow = INF;
              while ( node != source ) {
                 addFlow = min(addFlow, cap[p[node]][node] - flow[p[node]][node]);
                 node = p[node];
              }

              node = sink;
              while ( node != source ) {
                 flow[p[node]][node] += addFlow;
                 flow[node][p[node]] -= addFlow;
                 node = p[node];
              }
            }
         }
      }
   }

   bool edgevis[1 + MMAX];
   short critic[1 + MMAX];
   void dfs (int root) {
      for ( define_edge obj : g[root] ) {
         if ( !edgevis[obj.idx] ) {
           edgevis[obj.idx] = true;
           if ( cap[obj.to][root] == flow[obj.to][root] || cap[root][obj.to] == flow[root][obj.to] )
             critic[obj.idx] ++;
           else
             dfs (obj.to);
         }
      }
   }
   void iscritic () {
       for ( int e = 1; e <= MMAX; e ++ )
          edgevis[e] = false;
        dfs (source);
        for ( int e = 1; e <= MMAX; e ++ )
           edgevis[e] = false;
        dfs (sink);
        vector<int> answer;
        for ( int idx = 1; idx <= m; idx ++ )
           if ( critic[idx] == 2 )
             answer.push_back ( idx );
        out << answer.size () << "\n";
        for ( int idx : answer )
           out << idx << "\n";
   }
};

int main()
{
   in >> n >> m; MaxFlow solver; solver.source = 1, solver.sink = n;
   for ( int idx = 1; idx <= m; idx ++ ) {
      int u, v, c; in >> u >> v >> c;
      solver.add_edge (u, v, c, idx);
   }
   solver.getFlow ();
   solver.iscritic ();


    return 0;
}