Cod sursa(job #672684)

Utilizator popoiu.georgeGeorge Popoiu popoiu.george Data 2 februarie 2012 22:01:25
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.63 kb
#include<stdio.h>
#include<queue>
#include<string.h>
#include<vector>
#define inf "cc.in"
#define outf "cc.out"
#define NMax 101
#define DMax 202
#define INF 0x3f3f3f3f
using namespace std;

const int S = 0, D = 201;
int N, C[DMax][DMax], Cost[DMax][DMax], F[DMax][DMax];
int Dist[DMax], From[DMax], in[DMax], go, rez;
vector<int> G[DMax];

void read()
{
	scanf("%d", &N);
	
	int w;
	for(int i=1; i<=N; i++) {
		for(int j=N+1; j<=2*N; j++) {
			scanf("%d", &w);
			Cost[i][j] = w; Cost[j][i] = -w;
			C[i][j] = 1;
			G[i].push_back(j);
			G[j].push_back(i);
		}
	}	
	
	for(int i=1; i<=N; i++) { 
		C[S][i] = C[i+N][D] = 1;
		G[S].push_back(i); G[i].push_back(S);
		G[i+N].push_back(D); G[D].push_back(i+N);
	}
}

inline int min(int a, int b) { return a<b ? a : b; }

int BF() {
	for(int i=0; i<=D; i++) { Dist[i] = INF; From[i] = -1; }
	memset(in, 0, sizeof(in)); 
	
	Dist[S] = 0; in[S] = 1;
	queue<int> q; q.push(S);
	
	while( !q.empty() ) {
		int u = q.front(); q.pop();
		in[u] = 0;
		
		for(int i=0; i<G[u].size(); i++) {
			int v = G[u][i];
			if( C[u][v]-F[u][v]>0 && Dist[u]+Cost[u][v]<Dist[v] ) {
				Dist[v] = Dist[u]+Cost[u][v];
				From[v] = u;
				if( !in[v] ) { q.push(v); in[v] = 1; }
			}
		}
	}
	
	if( Dist[D]!=INF ) {
		go = 1;
		int fmin = INF, u;
		
		for( u=D; u!=S; u=From[u] ) fmin = min(fmin, C[From[u]][u]-F[From[u]][u] );
		
		for( u=D; u!=S; u=From[u] ) {
			F[From[u]][u] += fmin;
			F[u][From[u]] -= fmin;
		}
		
		return fmin*Dist[D];
	}
	
	return 0;
}

void solve()
{
	go = 1;
	while( go ) {
		go = 0;
		rez += BF();
	}	
	
	printf("%d", rez);
}

int main()
{
	freopen(inf,"r",stdin); freopen(outf,"w",stdout);
	read(); solve();
	return 0;
}