Cod sursa(job #2892356)

Utilizator DenisONIcBanu Denis Andrei DenisONIc Data 21 aprilie 2022 18:33:59
Problema Critice Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.69 kb
#include <bits/stdc++.h>
using namespace std;
void debug_out() { cerr << endl; }
template<class T> ostream& prnt(ostream& out, T v) { out << v.size() << '\n'; for(auto e : v) out << e << ' '; return out;}
template<class T> ostream& operator<<(ostream& out, vector <T> v) { return prnt(out, v); }
template<class T> ostream& operator<<(ostream& out, set <T> v) { return prnt(out, v); }
template<class T1, class T2> ostream& operator<<(ostream& out, map <T1, T2> v) { return prnt(out, v); }
template<class T1, class T2> ostream& operator<<(ostream& out, pair<T1, T2> p) { return out << '(' << p.first << ' ' << p.second << ')'; }
template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) { cerr << " " << H; debug_out(T...);}
#define dbg(...) cerr << #__VA_ARGS__ << " ->", debug_out(__VA_ARGS__)
#define dbg_v(x, n) do{cerr<<#x"[]: ";for(int _=0;_<n;++_)cerr<<x[_]<<" ";cerr<<'\n';}while(0)
#define dbg_ok cerr<<"OK!\n"
#define ll long long
#define ld long double
#define ull unsigned long long
#define pii pair<int,int>
#define MOD 1000000007
#define zeros(x) x&(x-1)^x
#define fi first
#define se second
#define NMAX 500005
const long double PI = acos(-1);

struct Dinic {
  struct Edge {
    int to, cap, flow, nxt, idx;
  };

  vector<Edge> edges;
  vector<int> graph, at, dist;
  int src = 0, dest = 1;

  Dinic(int n, int m = 0) : graph(n, -1), dist(n, -1) {
    edges.reserve(2*m);
  }

  void m_add_edge(int from, int to, int cap, int idx) {
    edges.push_back(Edge {to, cap, 0, graph[from], idx});
    graph[from] = edges.size() - 1;
  }
  void add_edge(int from, int to, int cap, int idx) {
    m_add_edge(from, to, cap, idx);
    m_add_edge(to, from, 0, idx);
  }

  void set_source_sink(int src, int dest) {
    this->src = src; this->dest = dest;
  }

  bool bfs(int step) {
    queue<int> q;
    fill(dist.begin(), dist.end(), -1);
    dist[src] = 0;
    q.push(src);

    while (!q.empty()) {
      int node = q.front(); q.pop();
      for (int i = graph[node]; i >= 0; i = edges[i].nxt) {
        const auto &e = edges[i];
        if (dist[e.to] == -1 && e.flow + step <= e.cap) {
          dist[e.to] = dist[node] + 1;
          q.push(e.to);
        }
      }
    }

    return dist[dest] != -1;
  }

  int dfs(int node, int flow) {
    if (flow == 0) return 0;
    if (node == dest) return flow;

    while (at[node] != -1) {
      int eid = at[node];
      const auto &e = edges[eid];

      if (dist[e.to] == dist[node] + 1) {
        if (int ret = dfs(e.to, min(flow, e.cap - e.flow))) {
          edges[eid].flow += ret;
          edges[eid^1].flow -= ret;
          return ret;
        }
      }

      at[node] = e.nxt;
    }

    return 0;
  }

  vector<vector<Edge>> get_graph(){
  	vector<vector<Edge>> end_graph;
    queue<int> q;

  	vector<int> viz;
  	viz.resize(graph.size(), 0);

  	end_graph.resize(graph.size());

  	q.push(src);

    while (!q.empty()) {
      int node = q.front(); q.pop();
      for (int i = graph[node]; i >= 0; i = edges[i].nxt) {
        const auto &e = edges[i];
        end_graph[node].push_back(e);
        if (!viz[e.to]) {
          viz[e.to] = 1;
          q.push(e.to);
        }
      }
    }

    return end_graph;
  }

  int compute() {
    int ret = 0, step = (1 << 30);

    while (step > 0) {
      if (!bfs(step)) step /= 2;
      else {
        at = graph;
        while (int flow = dfs(src, step))
          ret += flow;
      }
    }

    return ret;
  }
 
};

int viz[NMAX], viz2[NMAX];
void dfs(vector<vector<Dinic::Edge>> &gr, int viz[], int node) {
	viz[node] = 1;
	// dbg(node);

  for (auto it : gr[node]){
  	int to = it.to;
  	// dbg(node, to, it.flow, it.cap);
  	if (viz[to] || it.flow == it.cap) continue;
  	dfs(gr, viz, to);
  }
}

int main(){
  ios::sync_with_stdio(false);
  freopen("critice.in", "r", stdin);
  freopen("critice.out", "w", stdout);
  int n, m;
  cin >> n >> m;
  Dinic *d = new Dinic(n);
  Dinic *dp = new Dinic(n);

  for (int i=1;i<=m;i++){
  	int a, b, c;
  	cin >> a >> b >> c;
  	a--;
  	b--;
  	d->add_edge(a, b, c, i);
  	d->add_edge(b, a, c, i);
  	dp->add_edge(b, a, c, i);
  	dp->add_edge(a, b, c, i);
  }
  d->set_source_sink(0, n-1);
  dp->set_source_sink(n-1, 0);

  int a = d->compute();
  int b = dp->compute();

  // dbg(a, b);

  vector<vector<Dinic::Edge>> gr1 = d->get_graph();
  vector<vector<Dinic::Edge>> gr2 = dp->get_graph();

  dfs(gr1, viz, 0);
  // dbg("======");
  dfs(gr2, viz2, n-1);

  vector<int> ans;
  for (int i=0;i<n;i++){
  	if (viz[i]){
  		for (auto it : gr1[i]){
  			// dbg(i, it.to);
  			if (viz2[it.to]){
  				ans.push_back(it.idx);
  			}
  		}
  	}
  }
	sort( ans.begin(), ans.end() );
	ans.erase( unique( ans.begin(), ans.end() ), ans.end() );
  cout << ans.size() << '\n';

  for (auto it : ans) cout << it << '\n';

  return 0;
}