Cod sursa(job #2197895)

Utilizator DenisacheDenis Ehorovici Denisache Data 23 aprilie 2018 03:18:26
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.86 kb
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <fstream>
#include <limits.h>
#include <math.h>
#include <queue>
#include <set>
#include <array>
#include <bitset>

using namespace std;

int cap[1005][1005];
int flow[1005][1005];
int prv[1005];

vector<int> G[1005];
bitset<1005> used;

bool bfs(int source, int sink) {
	queue<int> Q;
	used.reset();

	Q.push(source);
	used[source] = 1;

	while (!Q.empty()) {
		int nod = Q.front();
		Q.pop();

		if (nod == sink) continue;

		for (auto& dest: G[nod]) {
			if (used[dest] || flow[nod][dest] == cap[nod][dest]) continue;

			Q.push(dest);
			prv[dest] = nod;
			used[dest] = 1;
		}
	}

	return used[sink];
}

int edmond_karp(int source, int sink) {
	int res = 0;
	const int INF = int(2e9);

	while (bfs(source, sink)) {
		for (auto& neigh: G[sink]) {
			if (flow[neigh][sink] == cap[neigh][sink] || !used[neigh]) continue;

			int minFlow = INF;

			prv[sink] = neigh;

			for (int i = sink; i != source; i = prv[i]) {
				minFlow = min(minFlow, cap[prv[i]][i] - flow[prv[i]][i]);
			}

			if (minFlow == 0) continue;

			for (int i = sink; i != source; i = prv[i]) {
				flow[prv[i]][i] += minFlow;
				flow[i][prv[i]] -= minFlow;
			}

			res += minFlow;
		}
	}

	return res;
}

int markings[2][1005];

void mark(int source, int type) {
	queue<int> Q;
	used.reset();

	Q.push(source);
	used[source] = 1;

	while (!Q.empty()) {
		int nod = Q.front();
		Q.pop();

		for (auto& dest : G[nod]) {
			if (used[dest]) continue;

			if (abs(flow[nod][dest]) == cap[nod][dest]) {
				markings[type][nod]++;
			}
			else {
				Q.push(dest);
				used[dest] = 1;
			}
		}
	}
}

struct Edge {
	int a, b;

	Edge() {}

	Edge(int a, int b) {
		this->a = a;
		this->b = b;
	}
};

int main() {
	ios::sync_with_stdio(false);

	string filename = "critice";

	ifstream cin(filename + ".in");
	ofstream cout(filename + ".out");

	int n, m;
	cin >> n >> m;

	vector< Edge > edges;

	for (int i = 1; i <= m; ++i) {
		int a, b, c;
		cin >> a >> b >> c;

		edges.emplace_back(a, b);

		G[a].push_back(b);
		G[b].push_back(a);

		cap[a][b] = c;
		cap[b][a] = c;
	}

	int initFlux = edmond_karp(1, n);
	set<int> critEdges;

	for (int i = 0; i < m; ++i) {
		if (abs(flow[edges[i].a][edges[i].b]) == cap[edges[i].a][edges[i].b])
			critEdges.insert(i + 1);
	}

	mark(1, 0);
	mark(n, 1);

	for (auto itr = critEdges.begin(); itr != critEdges.end(); ) {
		int idx = *itr;
		int a = edges[idx - 1].a;
		int b = edges[idx - 1].b;

		if ((markings[0][a] >= 1 && markings[1][b] >= 1) ||
			(markings[0][b] >= 1 && markings[1][a] >= 1)) ++itr;
		else itr = critEdges.erase(itr);
	}

	cout << critEdges.size() << "\n";
	
	for (auto& index : critEdges)
		cout << index << "\n";

	//system("pause");
	return 0;
}