Cod sursa(job #8979)

Utilizator vlad_DVlad Dumitriu vlad_D Data 26 ianuarie 2007 09:41:20
Problema A+B Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.84 kb
#include <cstdio>
#include <vector>
#include <set>
#include <stdlib.h>
#include <time.h>
using namespace std; 
int N;
int v[128][128];
int bN, vN[128];
int iz[128];
struct nod {
	int n, cost;
	nod(const int &_n, const int &_cost) {n = _n; cost = _cost;};
	nod(){};
	};
bool operator<(const nod &a, const nod &b) {
	if (a.cost < b.cost) return false;
	if (a.cost == b.cost) if (a.n < b.n) return false;
	return true;
	}
void in() {
	//freopen("croco.in", "r", stdin);
	//scanf("%d", &N);
	N = 110;
	srand(time(0)%123);
	int i, j;
	for (i=1; i<=N; i++) for (j=1; j<=N; j++) {int X;
	    if (i == j) X = 0;
		else X = rand()%222;
		//scanf("%d", &X);
		v[i][j] = X + 1; if (i == j) v[i][j]--;
	}
	//fclose(stdin);
	};

void out() {
	//freopen("croc.out", "w", stdout);
	int i;
	printf("%d %d\n", bN, vN[0]);
	for (i=1; i<vN[0]; i++) printf("%d ", vN[i]);
	printf("%d\n", vN[i]);
	fclose(stdout);
	};
void izoleaza(int source, int sink) {
	int fv[128][128], bv[128][128];
	int i, j;
	for (i=1; i<=N; i++) for (j=1; j<=N; j++) fv[i][j] = v[i][j], bv[i][j] = 0;
	int ret = 0;
	int D[128];
	while (true) {
		int drum[128];
		for (i=1; i<=N; i++) D[i] = 0;
		D[source] = 256;
		set<nod> Q;
		Q.insert(nod(source, 256));
		while (!Q.empty()) {
			// ia varful
			//relaxeaza-l
			nod top = *Q.begin();
			//printf("iese: %d %d\n", top.n, top.cost);
			Q.erase(Q.begin());
			//toate legaturile spargel
			for (i=1; i<=N; i++) if (i != top.n) {
				int c2 = top.cost; 
				if (fv[top.n][i] < c2) c2 = fv[top.n][i];
				if (c2 > D[i]) {
					//if (D[i] != 0) Q.erase(Q.find(nod(i, D[i])));
					D[i] = c2;
					Q.insert(nod(i, D[i]));
					drum[i] = top.n;
					};
				c2 = top.cost;
				if (bv[top.n][i] < c2) c2 = bv[top.n][i];
				if (c2 > D[i]) {
					//if (D[i] != 0) Q.erase(Q.find(nod(i, D[i])));
					D[i] = c2;
					Q.insert(nod(i, D[i]));
					drum[i] = top.n; 
					};
				}
			}
		//cauta drum
		//daca drum are d = 0 asta e fluxu :> say buy bay
		if (D[sink] == 0) break;
		//printf("flux: %d\n", D[sink]);
		int aci = sink;
		while (1) {
			if (aci == source) break;
			int aci2 = drum[aci];
			fv[aci2][aci]-=D[sink];
			bv[aci][aci2]+=D[sink];
			aci = aci2;
			}
		//printf("flux: %d\n", D[sink]);
		}
	//printf("crocodili: ");
	D[0] = 0; fv[0][0] = 0;
	for (i=1; i<=N; i++) if (D[i]) {
		D[++D[0]] = i;
	//	printf("%d ", i);
	} else {fv[0][++fv[0][0]] = i; iz[i] = 1;}
	int nmax = 0;
	for (i=1; i<D[0]; i++) for (j=i+1; j<=D[0]; j++) nmax+=v[D[i]][D[j]] - 1;
	for (i=1; i<fv[0][0]; i++) for (j=i+1; j<=fv[0][0]; j++) nmax+=v[fv[0][i]][fv[0][j]]-1;
	//printf("au pui: %d\n", nmax);
	if (nmax > bN ) {bN = nmax;
		vN[0] = D[0];
		for (i=1; i<=D[0]; i++) vN[i] = D[i];
		}
	};
int main() {
	in();
	int i;
	bN = -1;

	iz[1] = 1;
	for (i = 2; i<=N; i++) izoleaza(1, i);
	out();
	return 0;
}