Cod sursa(job #1741092)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 12 august 2016 23:01:37
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.32 kb
#include <cstdio>
#include <cstring>

using namespace std;

#define MaxN 1000
#define MaxM 10000
#define NIL -1

struct Edge {
	int v, cap;
	int next;
} G[2 * MaxM];

int N, M;

int Q[MaxN];
int dist[MaxN];
int head[MaxN], adj[MaxN];

void addEdge(const int u, const int v, const int cap, const int position) {
	G[position].v = v;
	G[position].cap = cap;
	G[position].next = head[u];
	head[u] = position;
}

bool BFS() {
	int qHead = 0, qTail = 1;
	memset(dist, 0, 4 * N);
	dist[0] = 1;
	Q[0] = 0;
	while (qHead != qTail) {
		const int node = Q[qHead++];
		for (int i = head[node]; i != NIL; i = G[i].next) {
			if (G[i].cap > 0 && !dist[G[i].v]) {
				dist[G[i].v] = dist[node] + 1;
				Q[qTail++] = G[i].v;
			}
		}
	}
	return dist[N - 1];
}

int DFS(const int node, const int flow) {
    if (node == N - 1) {
        return flow;
    }
    for (; adj[node] != NIL; adj[node] = G[adj[node]].next) {
        if (G[adj[node]].cap > 0 && dist[G[adj[node]].v] == dist[node] + 1) {
            const int pushFlow = (flow < G[adj[node]].cap) ? flow : G[adj[node]].cap;
            const int pushed = DFS(G[adj[node]].v, pushFlow);
            if (pushed) {
                G[adj[node]].cap -= pushed;
                G[adj[node] ^ 1].cap += pushed;
                return pushed;
            }
        }
    }
    return 0;
}

void getFlow() {
	while (BFS()) {
		memmove(adj, head, 4 * N);
		while (DFS(0, 0x3f3f3f3f));
	}
}

int mark[MaxN];

void fillEdges(const int node, const int type) {
	mark[node] = type;
	for (int i = head[node]; i != NIL; i = G[i].next) {
		if (G[i].cap > 0 && !mark[G[i].v]) {
			fillEdges(G[i].v, type);
		}
	}
}

int main() {
	freopen("critice.in", "rb", stdin);
	freopen("critice.out", "wb", stdout);

	scanf("%d %d", &N, &M);
	memset(head, NIL, 4 * N);
	for (int i = 0; i < M; i++) {
		int x, y, cap;
		scanf("%d %d %d", &x, &y, &cap);
		addEdge(x - 1, y - 1, cap, 2 * i);
		addEdge(y - 1, x - 1, cap, 2 * i + 1);
	}

	getFlow();

	fillEdges(0, 1);
	fillEdges(N - 1, 10);

	int numEdges = 0;
	for (int i = 0; i < M; i++) { 
		numEdges += ((G[2 * i].cap == 0 || G[2 * i + 1].cap == 0) && (mark[G[2 * i].v] + mark[G[2 * i + 1].v] == 11));
	}
	printf("%d\n", numEdges);
	for (int i = 0; i < M; i++) {
		if ((G[2 * i].cap == 0 || G[2 * i + 1].cap == 0) && (mark[G[2 * i].v] + mark[G[2 * i + 1].v] == 11)) {
			printf("%d\n", i + 1);
		}
	}
	return 0;
}