Cod sursa(job #138747)

Utilizator pauldbPaul-Dan Baltescu pauldb Data 19 februarie 2008 02:08:54
Problema Paznici2 Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.96 kb
#include <stdio.h>
#include <vector>

using namespace std;

#define maxn 410
#define maxm 210
#define S 0
#define D 2*n+1
#define pb push_back
#define inf 1000000000

int n,rez;
vector <int> a[maxn],b[maxn];
int g[maxn];
char c[maxn][maxn],f[maxn][maxn];
char sol[maxm][maxm];
int cost[maxn],from[maxn];
int dist[maxm][maxn];

int BellmanFord(int nod)
{
	int i,j,stop = 0,pas = 0;

	for (i=S;i<=D;i++) cost[i] = inf;
	cost[nod] = 0;

	while (!stop && pas < 100)
	{
		stop = 1;
		pas++;

		for (i=S;i<=D;i++) 
			for (j=0;j<g[i];j++)
				if (c[i][a[i][j]] - f[i][a[i][j]] > 0 && cost[i] + b[i][j] < cost[a[i][j]])
				{
					stop = 0;
					from[a[i][j]] = i;
					cost[a[i][j]] = cost[i] + b[i][j];
				}
	}

	return cost[D];
}

void recon()
{
	int i = D;
	while (i != S)
	{
		f[from[i]][i]++;
		f[i][from[i]]--;
		i = from[i];
	}
}

int Flux()
{
	int i, rez = 0;
	for (i=1;i<=n;i++) 
	{
		rez += BellmanFord(S);
		recon();
	}

	return rez;
}

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

	int i,j,x;
	int mark,leg;

	scanf("%d ",&n);

	for (i=1;i<=n;i++)
	{
		for (j=n+1;j<=2*n;j++)
		{
			scanf("%d ",&x);
			a[i].pb(j);
			a[j].pb(i);
			b[i].pb(x);
			b[j].pb(-x);
			c[i][j] = 1;
		}
		a[i].pb(S);
		a[S].pb(i);
		b[i].pb(0);
		b[S].pb(0);
		c[S][i] = 1;

		a[i+n].pb(D);
		a[D].pb(i+n);
		b[i+n].pb(0);
		b[D].pb(0);
		c[i+n][D] = 1;
	}

	for (i=S;i<=D;i++) g[i] = a[i].size();

	rez = Flux();

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

	for (i=1;i<=n;i++) 
	{
		BellmanFord(i+n);

		memcpy(dist[i],cost,sizeof(cost));
	}

	for (i=1;i<=n;i++)
	{
		mark = leg = 0;
		for (j=0;j<g[i];j++)
			if (f[i][a[i][j]]==1) 
			{
				mark = a[i][j];
				leg = b[i][j];
			}

		for (j=0;j<g[i];j++)
			if (a[i][j] > n && a[i][j] < D && b[i][j] + dist[a[i][j]-n][mark] == leg) sol[i][a[i][j]-n] = 1;
	}

	for (i=1;i<=n;i++)
	{
		x = 0;

		for (j=1;j<=n;j++) 
			if (sol[j][i]) x++;
		printf("%d ",x);

		for (j=1;j<=n;j++)
			if (sol[j][i]) printf("%d ",j);
		printf("\n");
	}

	return 0;
}