Cod sursa(job #751605)

Utilizator ChallengeMurtaza Alexandru Challenge Data 26 mai 2012 13:59:39
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

const char InFile[]="cc.in";
const char OutFile[]="cc.out";
const int MaxN=105;
const int MaxNodes=2*MaxN;
const int INF=1<<30;

ifstream fin(InFile);
ofstream fout(OutFile);

int N,S,D,x,C[MaxNodes][MaxNodes],F[MaxNodes][MaxNodes],Cost[MaxNodes][MaxNodes];
bool ok;
vector<int> G[MaxNodes];
queue<int> Q;
char inQ[MaxNodes];
int Dist[MaxNodes],From[MaxNodes];

inline int BellmanFord()
{
	ok=false;
	for(register int i=0;i<=D;++i)
	{
		From[i]=0;
		Dist[i]=INF;
	}

	Dist[S]=0;
	Q.push(S);
	inQ[S]=1;
	while(!Q.empty())
	{
		int nod=Q.front();
		Q.pop();
		inQ[nod]=0;

		for(vector<int>::iterator it=G[nod].begin();it!=G[nod].end();++it)
		{
			if(C[nod][*it]-F[nod][*it]>0)
			{
				if(Dist[*it]>Dist[nod]+Cost[nod][*it])
				{
					Dist[*it]=Dist[nod]+Cost[nod][*it];
					From[*it]=nod;
					if(!inQ[*it])
					{
						inQ[*it]=1;
						Q.push(*it);
					}
				}
			}
		}
	}

	if(Dist[D]!=INF)
	{
		ok=true;
		int minim=INF;
		int t=D;
		for(;t!=S;t=From[t])
		{
			if(minim>C[From[t]][t]-F[From[t]][t])
			{
				minim=C[From[t]][t]-F[From[t]][t];
			}
		}
		t=D;
		for(;t!=S;t=From[t])
		{
			F[From[t]][t]+=minim;
			F[t][From[t]]-=minim;
		}
		return Dist[D]*minim;
	}

	return 0;
}

inline int MinCostMaxFlow()
{
	int sol=0;
	ok=true;
	while(ok)
	{
		sol+=BellmanFord();
	}
	return sol;
}

inline void Connect(int from, int to, int cost)
{
	G[from].push_back(to);
	G[to].push_back(from);
	C[from][to]=1;
	Cost[from][to]=cost;
	Cost[to][from]=-cost;
}

int main()
{
	fin>>N;
	S=2*(N+1);
	D=S+1;
	for(register int i=1;i<=N;++i)
	{
		Connect(S,(i<<1),0);
		Connect((i<<1)+1,D,0);
		for(register int j=1;j<=N;++j)
		{
			fin>>x;
			Connect(i<<1,(j<<1)+1,x);
		}
	}
	fin.close();

	fout<<MinCostMaxFlow();
	fout.close();
	return 0;
}