Cod sursa(job #371015)

Utilizator victor.ionescuIonescu Victor Cristian victor.ionescu Data 3 decembrie 2009 01:18:15
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.94 kb
#include <fstream>
#include <list>
#include <vector>
#define MAX 220
#define inf 2000000000
using namespace std;
ifstream fi("cc.in");
ofstream fo("cc.out");
int N,DHeap,Dist[MAX],heap[MAX],T[MAX],C[MAX][MAX],F[MAX][MAX],poz[MAX];
vector<pair<int,int> > G[MAX],Gi[MAX];
list<int> L;

int BellmanFord(int S,int D){
	for (int i=1;i<=N;++i){ Dist[i]=inf;T[i]=-1; }
	Dist[S]=0;
	L.push_back(S);
	while (!L.empty()){
		list<int>::iterator it=L.begin();
		for (unsigned int i=0;i<G[*it].size();++i)
			if (C[*it][G[*it][i].first]-F[*it][G[*it][i].first]>0)
				if (Dist[G[*it][i].first]>(Dist[*it]+G[*it][i].second)){
					T[G[*it][i].first]=*it;
					Dist[G[*it][i].first]=Dist[*it]+G[*it][i].second;
					L.push_back(G[*it][i].first);
				}
		L.pop_front();
	}
	if (Dist[D]<inf) return 1; else return 0;
}

void swap(int i,int j){
	int aux=heap[i];heap[i]=heap[j];heap[j]=aux;
	poz[heap[i]]=i;poz[heap[j]]=j;
}

void heap_up(int nod){
	int dad=(nod/2);
	if (dad && Dist[heap[dad]]>Dist[heap[nod]]){
		swap(nod,dad);
		heap_up(dad);
	}
}

void heap_dw(int nod){
	int l=nod*2,r=l+1,minim=nod;
	if (l<=DHeap && Dist[heap[l]]<Dist[heap[minim]]) minim=l;
	if (r<=DHeap && Dist[heap[r]]<Dist[heap[minim]]) minim=r;
	if (minim!=nod){
		swap(nod,minim);
		heap_dw(minim);
	}
}

int Dijkstra(int S,int D){
	for (int i=1;i<=N;++i)
		for (unsigned int j=0;j<G[i].size();++j)
			if (Dist[i]!=inf && Dist[G[i][j].first]!=inf) G[i][j].second+=(Dist[i]-Dist[G[i][j].first]);
	DHeap=N;
	for (int i=1;i<=N;++i){
		Dist[i]=inf;
		T[i]=-1;
		heap[i]=i;
		poz[i]=i;
	}
	Dist[S]=0;
	heap_up(poz[S]);
	while (DHeap && Dist[heap[1]]!=inf){
		int nod=heap[1];
		for (unsigned int i=0;i<G[nod].size();++i)
			if (C[nod][G[nod][i].first]-F[nod][G[nod][i].first]>0)
				if (Dist[G[nod][i].first]>(Dist[nod]+G[nod][i].second)){
					Dist[G[nod][i].first]=Dist[nod]+G[nod][i].second;
					T[G[nod][i].first]=nod;
					heap_up(poz[G[nod][i].first]);
				}
		swap(1,DHeap);
		--DHeap;
		heap_dw(1);
	}
	if (Dist[D]<inf) return 1; else return 0;
}

int cost(int sursa,int dest){
	if (!BellmanFord(sursa,dest)) return 0;
	int rez=0;
	while (Dijkstra(sursa,dest)){
		int maxflow=inf;
		for (int nod=dest;nod!=sursa;nod=T[nod]) maxflow=min(maxflow,C[T[nod]][nod]-F[T[nod]][nod]);
		if (maxflow>0)
			for (int nod=dest;nod!=sursa;nod=T[nod]) { F[T[nod]][nod]+=maxflow; F[nod][T[nod]]-=maxflow; }
	}
	for (int i=1;i<=(N-2)/2;++i)
		for (unsigned int j=0;j<Gi[i].size();++j)
			rez+=F[i][Gi[i][j].first]*Gi[i][j].second;
	return rez;
}

int main(){
	fi>>N;
	int x;
	for (int i=1;i<=N;++i)
		for (int j=1;j<=N;++j){
			fi>>x;
			G[i].push_back(make_pair(N+j,x));
			G[N+j].push_back(make_pair(i,-x));
			Gi[i].push_back(make_pair(N+j,x));
			C[i][N+j]=1;
		}
	for (int i=1;i<=N;++i){
		C[N*2+1][i]=1;
		G[N*2+1].push_back(make_pair(i,0));
		G[i].push_back(make_pair(N*2+1,0));
		C[N+i][N*2+2]=1;
		G[N+i].push_back(make_pair(N*2+2,0));
		G[N*2+2].push_back(make_pair(N+i,0));
	}
	N=N*2+2;
	fo<<cost(N-1,N)<<"\n";
	fi.close();
	fo.close();
	return 0;
}