Cod sursa(job #144453)

Utilizator alextheroTandrau Alexandru alexthero Data 27 februarie 2008 17:56:36
Problema Paznici2 Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.9 kb
#include <stdio.h>
#include <string.h>
#include <algorithm>

#define nmax 405
#define inf 0x3f3f3f3f

using namespace std;

int n, sol, dest;
int d[nmax], prev[nmax], D[nmax][nmax];
int cap[nmax][nmax], cost[nmax][nmax];
char p[nmax][nmax];

void drum(int x)
{
	int ok;
	memset(d, inf, sizeof(d));
	d[x] = 0, prev[x] = -1;

	do {
		ok = 1;
		for(int i = 0; i <= dest; i++)
			if(d[i] != inf)
				for(int j = 0; j <= dest; j++)
					if(cap[i][j] > 0 && d[i] + cost[i][j] < d[j])
					{
						ok = 0;
						d[j] = d[i] + cost[i][j];
						prev[j] = i;
					}
	} while(!ok);
}

void reconst(int last)
{
	int x = last, minim = inf;
	while(prev[x] != -1)
	{
		minim = min(minim, cap[prev[x]][x]);
		x = prev[x];
	}

	x = last;
	while(prev[x] != -1)
	{
		cap[prev[x]][x] -= minim;
		cap[x][prev[x]] += minim;
		x = prev[x];
	}
}

int flux()
{
	int sol = 0;
	
	while(1)
	{
		drum(0);
		if(d[dest] == inf) return sol;
		sol += d[dest];
		reconst(dest);
	}

	return sol;
}

int main()
{
	freopen("paznici2.in", "r", stdin);
	freopen("paznici2.out", "w", stdout);
	
	scanf("%d", &n); dest = 2 * n + 1;
	for(int i = 1; i <= n; i++)
	{
		cap[0][i] = 1;
		cost[0][i] = 0;
		for(int j = 1; j <= n; j++) 
		{
			int tmp;
			scanf("%d ", &tmp);
			cost[i][j + n] = tmp;
			cost[j + n][i] = -tmp;
			cap[i][j + n] = 1;
		}
		cap[i + n][dest] = 1;
		cost[i + n][dest] = 0;
	}

	sol = flux();
	printf("%d\n", sol);

	for(int i = n + 1; i < dest; i++) 
	{
		drum(i);
		for(int j = 0; j <= dest; j++) D[i][j] = d[j];
	}

	for(int i = 1; i <= n; i++)
	{
		int cuplat = 0, c = 0;

		for(int j = n + 1; j < dest; j++)
			if(cap[i][j] == 0) cuplat = j, c = cost[i][j];

		for(int j = n + 1; j < dest; j++)
			if(cost[i][j] + D[j][cuplat] == c) p[i][j - n] = 1;
	}

	for(int j = 1; j <= n; j++)
	{
		int tot = 0;
		for(int i = 1; i <= n; i++) tot += p[i][j];
		printf("%d ", tot);
		for(int i = 1; i <= n; i++)	if(p[i][j]) printf("%d ", i);
		printf("\n");
	}
	return 0;
}