Cod sursa(job #1474745)

Utilizator theprdvtheprdv theprdv Data 22 august 2015 19:47:27
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.53 kb
#define _CRT_SECURE_NO_DEPRECATE
#include <queue>
#include <algorithm>
#include <cstring>
#define MAXN 1001
#define DIM (1 << 13)
#define in (read_int())
#define foreach(G)  for (Node *it = (G); it; it = it->link)
#define foreachP(G) for (pair_Node *it = (G); it; it = it->link)

using namespace std;

struct elem{
	int fl, cp, ord;
};

struct Node{
	int val, sz;
	Node *link;

	inline void push_front(Node*&head, int val){
		Node *New = new Node;
		New->link = this, New->val = val, New->sz = !head ? 1 : head->sz + 1;
		head = New;
	}

	inline int size(){
		return this->sz;
	}
} *list[MAXN], *out;

struct pair_Node{
	int first, second;
	pair_Node *link;

	inline void push_front(pair_Node *&head, int first, int second){
		pair_Node *New = new pair_Node;
		New->first = first, New->second = second, New->link = head;
		head = New;
	}
} *sol;

int N, M, T[MAXN], used[MAXN], flow, len, bpos = DIM;
elem netw[MAXN][MAXN];
queue <int> q;
char buf[DIM];

inline int read_int(){
	while (buf[bpos] < '0' || buf[bpos] > '9'){
		++bpos;
		if (bpos >= DIM) len = (int)fread(buf, 1, DIM, stdin), bpos = 0;
	}

	int val = 0;
	while (buf[bpos] <= '9' && buf[bpos] >= '0'){
		if (bpos == len) break;
		val = val * 10 + buf[bpos] - '0';
		if (++bpos == DIM) len = (int)fread(buf, 1, DIM, stdin), bpos = 0;
	}
	return val;
}

inline void write(int k){
	char lim[30], *s;
	s = lim + 29, *s = 0;

	do{
		--s;
		*s = k % 10 + '0';
		k /= 10;
	} while (k);
	puts(s);
}

void read()
{
	N = in, M = in;
	for (int i = 1, x, y, c; i <= M; i++)
		x = in, y = in, c = in,
		netw[x][y].cp = netw[y][x].cp = c,
		netw[x][y].ord = netw[y][x].ord = i,
		list[x]->push_front(list[x], y),
		list[y]->push_front(list[y], x);
}

int BFS()
{
	memset(used, false, sizeof(int) * N + 1);
	q.push(1);
	used[1] = 1;

	while (!q.empty()){
		int node = q.front();
		q.pop();
		if (node == N) continue;

		foreach(list[node]){
			int new_node = it->val;
			if (used[new_node] || netw[node][new_node].fl == netw[node][new_node].cp) continue;
			used[new_node] = 1;
			q.push(new_node);
			T[new_node] = node;
		}
	}
	return used[N];
}
void BFS2()
{
	int node, new_node;
	q.push(1), q.push(N);
	used[1] = -1, used[N] = -2;

	while (!q.empty()){
		node = q.front();
		q.pop();
		foreach(list[node]){
			new_node = it->val;
			if (used[new_node] == used[node]) continue;
			if (netw[node][new_node].cp - netw[node][new_node].fl == 0 || netw[new_node][node].cp - netw[new_node][node].fl == 0){
				if (used[node] == -2)
					sol->push_front(sol, node, new_node);
				continue;
			}
			q.push(new_node);
			used[new_node] = used[node];
		}
	}
}

int main()
{
	freopen("critice.in", "r", stdin);
	freopen("critice.out", "w", stdout);
	read();
	used[N] = true;

	while (BFS()){
		foreach(list[N]){
			T[N] = it->val;
			if (!T[N] || netw[T[N]][N].cp - netw[T[N]][N].fl == 0) continue;
			int minf = ~(1 << 31);

			for (int node = N, newf; node != 1; node = T[node]){
				newf = netw[T[node]][node].cp - netw[T[node]][node].fl;
				if (newf < minf)  minf = newf;
			}
			if (!minf) continue;

			for (int node = N; node != 1; node = T[node])
				netw[T[node]][node].fl += minf,
				netw[node][T[node]].fl -= minf;
			flow += minf;
		}
	}
	BFS2();
	foreachP(sol){
		if (used[it->first] == used[it->second] || used[it->first] == 0 || used[it->second] == 0)
			continue;
		out->push_front(out, netw[it->first][it->second].ord);
	}
	write(out->size());
	foreach(out)
		write(it->val);
	
	return 0;
}