Cod sursa(job #751495)

Utilizator PetcuIoanPetcu Ioan Vlad PetcuIoan Data 26 mai 2012 11:13:54
Problema Cc Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.34 kb
#include<stdio.h>
#include<vector>
#include<queue>
#include<cstring>

#define maxn 355
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define INF 0x3f3f3f3f

using namespace std;

FILE*f=fopen("cc.in","r");
FILE*g=fopen("cc.out","w");

int n,m,S,D,L;
int dist[maxn],inq[maxn],H[maxn],Poz[maxn];
int T[maxn],C[maxn][maxn],F[maxn][maxn];
vector< pii >G[maxn];
queue<int>Q;

inline void citire () {

	fscanf(f,"%d",&n);

	m = n * (n + 2);

	S = 0;
	D = 2 * n + 1;

	for(int i = 1; i <= n; ++i){
    for(int j = 1; j <= n; ++j){
      int aux;
      fscanf(f, "%d", &aux);

      G[i].pb(mp(n + j, aux));
      G[n + j].pb(mp(i, -aux));
      C[i][n + j] = 1;
    }

      C[S][i] = 1;
      G[S].pb(mp(i, 0));
      G[i].pb(mp(S, 0));

      C[i + n][D] = 1;
      G[i + n].pb(mp(D, 0));
      G[D].pb(mp(i + n, 0));
	}

  n = n * 2 + 1;
}

inline void bellman_ford () {
	int nod;

	Q.push(S); inq[S] = 1;
	memset(dist,INF,sizeof(dist));
	dist[S] = 0;

	while ( !Q.empty() ){
		nod = Q.front(); Q.pop(); inq[nod] = 0;

		for ( vector< pii >::iterator itt = G[nod].begin() ; itt != G[nod].end() ; ++itt ){
			int nodvcn = itt->first; int cost = itt->second;
			if ( dist[nodvcn] > dist[nod] + cost && C[nod][nodvcn] > F[nod][nodvcn] ){
				dist[nodvcn] = dist[nod] + cost;

				if ( !inq[nodvcn] ){
					Q.push(nodvcn); inq[nodvcn] = 1;
				}
			}
		}
	}
}

inline void update_costs () {

	for ( int i = 1 ; i <= n ; ++i ){
		for ( vector< pii >::iterator itt = G[i].begin() ; itt != G[i].end() ; ++itt ){
			int nodvcn = itt->first; int cost = itt->second;
			itt->second = cost + dist[i] - dist[nodvcn];
		}
	}
}

inline void swap ( int &a , int &b ){
	int aux = a ; a = b ; b = aux;
}

inline void urca ( int poz ){

	while ( poz > 1 && dist[H[poz>>1]] > dist[H[poz]] ){
		swap(H[poz>>1],H[poz]);
		swap(Poz[H[poz>>1]],Poz[H[poz]]);
		poz >>= 1;
	}
}

inline void coboara ( int x ){
	int y = 0;

	while ( x != y ){
		y = x;

		if ( 2*y <= L && dist[H[2*y]] < dist[H[x]] ){
			x = 2*y;
		}
		if ( 2*y+1 <= L && dist[H[2*y+1]] < dist[H[x]] ){
			x = 2*y+1;
		}

		swap(H[x],H[y]);
		swap(Poz[H[x]],Poz[H[y]]);
	}
}

inline void insert ( int nod ){

	H[++L] = nod; Poz[nod] = L;
	urca(L);
}

inline int pop () {
	int nod = H[1];

	swap(H[1],H[L]); swap(Poz[H[1]],Poz[H[L]]);
	H[L] = Poz[H[L]] = 0; --L;
	coboara(1);

	return nod;
}

inline bool dijkstra () {
	int nod;

	memset(dist,INF,sizeof(dist)); dist[S] = 0;
	insert(S);

	while ( L ){
		nod = pop();

		for ( vector< pii >::iterator itt = G[nod].begin() ; itt != G[nod].end() ; ++itt ){
			int nodvcn = itt->first; int cost = itt->second;

			if ( dist[nodvcn] > dist[nod] + cost && C[nod][nodvcn] > F[nod][nodvcn] ){
				dist[nodvcn] = dist[nod] + cost; T[nodvcn] = nod;

				if ( Poz[nodvcn] ){
					urca(Poz[nodvcn]);
				}
				else{
					insert(nodvcn);
				}
			}
		}
	}

	return dist[D] != INF;
}

inline void fmcm () {
	int cost = 0,lasttoD,minim,nod;

	bellman_ford(); lasttoD = dist[D];
	update_costs();

	while ( dijkstra() ){

		minim = INF;
		for ( nod = D ; T[nod] ; nod = T[nod] ){
			minim = min(minim,C[T[nod]][nod] - F[T[nod]][nod]);
		}
		for ( nod = D ; T[nod] ; nod = T[nod] ){
			F[T[nod]][nod] += minim;
			F[nod][T[nod]] -= minim;
		}

		cost += dist[D]*minim + lasttoD*minim; lasttoD += dist[D];
		update_costs();
	}

	fprintf(g,"%d\n",cost);
}

int main () {

	citire();
	fmcm();

	fclose(f);
	fclose(g);

	return 0;
}