Cod sursa(job #826121)

Utilizator elfusFlorin Chirica elfus Data 30 noiembrie 2012 02:44:24
Problema Critice Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.53 kb
#include <stdio.h>
#include <string.h>
#include <vector>
#include <algorithm>
#define NMAX 215

using namespace std;

int C[NMAX][NMAX], F[NMAX][NMAX], ord[NMAX][NMAX], vis2[NMAX], vis3[NMAX], TT[NMAX];
vector <int> G[NMAX];
int sol[4000];

void init(int N)
{
	int i, j;
	
	for (i = 1; i <= N; i ++)
		for (j = 1; j <= N; j ++)
			F[i][j] = 0;
}

bool BFS(int sink, int N)
{
	int p = 1, u = 0, i, inQ[NMAX], vis[NMAX];
	vector <int> :: iterator it;
	
	for (i = 1; i <= N; i ++)
	{
		vis[i] = 0;
		TT[i] = 0;
	}
	inQ[++ u] = 1; vis[1] = 1;
	
	while (p <= u)
	{
		int nod = inQ[p];
		for (it = G[nod].begin(); it != G[nod].end(); it ++)
			if (F[nod][*it] < C[nod][*it] && !vis[*it])
			{
				inQ[++ u] = *it;
				TT[*it] = nod;
				vis[*it] = 1;
			}
		
		p ++;
	}
	
	return vis[sink];
}

int augment(int sink)
{
	int ftot = 0, flux = 1 << 30, nod = sink;
	vector <int> :: iterator it;
	
	for (it = G[sink].begin(); it != G[sink].end(); it ++)
	{
		flux = C[*it][sink] - F[*it][sink];
		nod = *it;
		
		while (nod > 1 && flux)
		{
			if (C[TT[nod]][nod] - F[TT[nod]][nod] < flux)
				flux = C[TT[nod]][nod] - F[TT[nod]][nod];
			nod = TT[nod];
		}
		
		if (flux)
		{
			F[*it][sink] += flux; F[sink][*it] -= flux;
			int nod = *it;
			while (nod > 1)
			{
				F[TT[nod]][nod] += flux;
				F[nod][TT[nod]] -= flux;
				nod = TT[nod];
			}
			ftot += flux;
		}
	}
	
	
	return ftot;
}

void DFS(int nod)
{
	vector <int> :: iterator it;
	
	vis2[nod] = 1;
	for (it = G[nod].begin(); it != G[nod].end(); it ++)
		if (F[nod][*it] < C[nod][*it] && !vis2[*it])
			DFS(*it);
}

void cutIt(int nod)
{
	vector <int> :: iterator it;
	
	vis3[nod] = 1;
	for (it = G[nod].begin(); it != G[nod].end(); it ++)
		if (!vis3[*it])
		{
			if (vis2[*it])
				cutIt(*it);
			else
				sol[++ sol[0]] = ord[nod][*it];
		}
}

int main()
{
	int i, N, M;
	
	freopen("sabotaj.in", "r", stdin);
	freopen("sabotaj.out", "w", stdout);
	
	scanf("%d%d", &N, &M);
	for (i = 1; i <= M; i ++)
	{
		int x0, y0, c;
		scanf("%d%d%d", &x0, &y0, &c);
		C[x0][y0] = C[y0][x0] = c;
		G[x0].push_back(y0);
		G[y0].push_back(x0);
		ord[x0][y0] = ord[y0][x0] = i;
	}
	
	int sink, mcut = 1 << 30;
	for (sink = 2; sink <= N; sink ++)
	{
		int cut = 0;
	
		init(N);
		while (BFS(sink, N))
			cut += augment(sink);
		if (cut < mcut)
		{
			mcut = cut;
			memset(vis2, 0, sizeof(vis2));
			memset(vis3, 0, sizeof(vis3));
			sol[0] = 0;
			
			DFS(1);
			cutIt(1);
		}
	}
	
	sort(sol + 1, sol + sol[0] + 1);
	printf("%d %d\n", mcut, sol[0]);
	for (i = 1; i <= sol[0]; i ++)
		printf("%d\n", sol[i]);
	
	return 0;
}