Cod sursa(job #134174)

Utilizator ProstuStefan-Alexandru Filip Prostu Data 10 februarie 2008 20:18:34
Problema Paznici2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.16 kb
#include <cstdio>
#include <queue>
#include <vector>

using namespace std;

#define PB push_back

const int NMAX = 204;
const int MMAX = 408;
const int INF = 0x3f3f3f3f;

int N, N2, dest, best;
int F[MMAX][MMAX], C[MMAX][MMAX], cost[MMAX][MMAX];
vector <int> G[MMAX], sol[NMAX];
int T[MMAX], D[MMAX];
int dist[MMAX][MMAX];

void read(void) {
	FILE *fin = fopen("paznici2.in", "rt");
	int i, j;

	fscanf(fin, " %d", &N);
	N2 = N << 1;
	dest = N2 + 1;

	for (i = 1; i <= N; ++i) {
		G[0].PB(i); G[i].PB(0);
		G[N+i].PB(dest); G[dest].PB(N+i);
		C[0][i] = C[N+i][dest] = 1;
		C[i][0] = C[dest][N+i] = -INF;
		for (j = N+1; j <= N2; ++j) {
			G[i].PB(j); G[j].PB(i);
			fscanf(fin, " %d", cost[i] + j);
			cost[j][i] = -cost[i][j];
			C[i][j] = 1;
		}
	}

	fclose(fin);
}

int bellman_ford(int S) {
	int u, v;
	queue <int> Q;
	bool V[MMAX];
	vector <int> :: iterator p;

	memset(D, 0x3f, sizeof(D));
	memset(V, 0x00, sizeof(V));
	D[S] = 0; V[S] = true;
	for (Q.push(S); !Q.empty(); Q.pop()) {
		u = Q.front();
		V[u] = false;

		for (p = G[u].begin(); p != G[u].end(); ++p) {
			v = *p;
			if (D[v] > D[u] + cost[u][v] && F[u][v] < C[u][v]) {
				D[v] = D[u] + cost[u][v];
				T[v] = u;
				if (V[v] == false)
					V[v] = true, Q.push(v);
			}
		}
	}
	return D[dest];
}

int flux(void) {
	int c, u, v, cost = 0, flux;

	while ((c = bellman_ford(0)) != INF) {
		cost += c;
		flux = INF;
		for (u = T[v = dest]; v; u = T[v = u])
			flux = min(flux, C[u][v] - F[u][v]);
		for (u = T[v = dest]; v; u = T[v = u])
			F[u][v] += 1, F[v][u] -= 1;
	}
	return cost;
}

void write(void) {
	FILE *fout = fopen("paznici2.out", "wt");

	int i, j, r;

	best = flux();
	fprintf(fout, "%d\n", best);
	
	for (i = N+1; i <= N2; ++i) {
		bellman_ford(i);
		memcpy(dist[i], D, sizeof(D));
	}

	for (i = 1; i <= N; ++i) {
		for (j = N+1, r = 0; j <= N2 && r == 0; ++j)
			if (F[i][j]) r = j;

		for (j = N+1; j <= N2; ++j)
			if (cost[i][j] + dist[j][r] == cost[i][r])
				sol[j-N].PB(i);
	}

	for (i = 1; i <= N; ++i) {
		fprintf(fout, "%u", sol[i].size());

		for (j = 0; j < (int) sol[i].size(); ++j)
			fprintf(fout, " %d", sol[i][j]);
		fprintf(fout, "\n");
	}

	fclose(fout);
}

int main(void) {

	read();

	write();

	return 0;
}