Cod sursa(job #142773)

Utilizator gcosminGheorghe Cosmin gcosmin Data 25 februarie 2008 09:32:30
Problema Paznici2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.28 kb
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;

#define NMAX 410
#define INF 1000000000
#define ff first
#define ss second
#define MP make_pair

int N;

vector <pair<int, int> > leg[NMAX];

int dst[NMAX][NMAX];

char cap[NMAX][NMAX];
int coada[NMAX * NMAX];
int dist[NMAX];
int pred[NMAX];
char in_coada[NMAX];

vector <int> sol[NMAX];

int bf(int beg)
{
	int p = 0, q = 0, i, x, y, c;
	vector <pair<int, int> > :: iterator it;

	for (i = 0; i <= 2 * N + 1; i++) dist[i] = INF;

	coada[0] = beg;
	dist[beg] = 0;
	in_coada[beg] = 1;
	pred[beg] = 0;

	while (p <= q) {
		x = coada[p];
		in_coada[x] = 0;
		p++;

		for (it = leg[x].begin(); it != leg[x].end(); ++it) {
//			printf("%d ", it->ff);
			y = it->ff; c = it->ss;

			if (dist[x] + c < dist[y] && cap[x][y]) {
				dist[y] = dist[x] + c;
				pred[y] = x;

				if (!in_coada[y]) in_coada[y] = 1, coada[++q] = y;
			}
		}
	}

	return dist[2 * N + 1] < INF;
}

int main()
{
	int i, j, q;

	freopen("paznici2.in", "r", stdin);
	freopen("paznici2.out", "w", stdout);

	scanf("%d", &N);

	for (i = 1; i <= N; i++)
		for (j = 1; j <= N; j++) {
			scanf("%d", &q);
			dst[i][j] = q;

			cap[i][N + j] = 1;
			leg[i].push_back(MP(N + j, q));
			leg[N + j].push_back(MP(i, -q));
		}

	for (i = 1; i <= N; i++) {
		leg[0].push_back(MP(i, 0));
		cap[0][i] = 1;

		leg[N + i].push_back(MP(2 * N + 1, 0));
		cap[N + i][2 * N + 1] = 1;
	}

	int cur, FL = 0;
	while (bf(0)) {
		cur = 2 * N + 1;

		FL += dist[2 * N + 1];

		while (cur) {
			cap[pred[cur]][cur]--;
			cap[cur][pred[cur]]++;
			cur = pred[cur];
		}
	}

	printf("%d\n", FL);

	// refac muchiile
	
	for (i = 1; i <= N; i++) leg[N + i].clear();
	
	for (i = 1; i <= N; i++) {
		leg[i].clear();

		for (j = 1; j <= N && cap[i][N + j]; j++);

		leg[i].push_back(MP(N + j, -dst[i][j]));

		for (j = 1; j <= N; j++) leg[N + j].push_back(MP(i, dst[i][j]));
	}

	for (i = 1; i <= N; i++)
		for (j = 1; j <= N; j++) 
			cap[i][N + j] = cap[N + j][i] = 1;

	// vad cine cu cine merge

	for (i = 1; i <= N; i++) {
		bf(i);

		for (j = 1; j <= N; j++) 
			if (dist[N + j] + dst[i][j] == 0) sol[j].push_back(i);
	}

	for (i = 1; i <= N; i++) {
		printf("%d ", (int) sol[i].size());

		for (vector <int> :: iterator it = sol[i].begin(); it != sol[i].end(); ++it) printf("%d ", *it);
		printf("\n");
	}

return 0;
}