Cod sursa(job #3191391)

Utilizator MarutBrabete Marius Stelian Marut Data 9 ianuarie 2024 17:00:02
Problema Cc Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.44 kb
#include<bits/stdc++.h>
using namespace std;
const int N=105*2;
const int INF=1e9;
int n,maxSize,source,sink;
int minCost,maxFlux;
int t[N],cap[N][N],flow[N][N],cost[N][N];
vector<int>G[N],realDist,newRealDist,positiveDist;
vector<bool>viz;
void BellmanFord()
{
	vector<bool>inCoada(maxSize, false);
	realDist.assign(maxSize,INF);
	queue<int>coada;
	coada.push(source);
	inCoada[source]=true;
	realDist[source]=0;
	while(!coada.empty())
	{
		int x=coada.front();
		coada.pop();
		inCoada[x]=false;
		for(int y:G[x])
		{
			if(flow[x][y]!=cap[x][y] && realDist[x]+cost[x][y]<realDist[y])
			{
				t[y]=x;
				realDist[y]=realDist[x]+cost[x][y];
				if(!inCoada[y])
				{
					coada.push(y);
					inCoada[y]=true;
				}
			}
		}
	}
}
void Dijkstra()
{
	positiveDist.assign(maxSize,INF);
	newRealDist.assign(maxSize,INF);
	viz.assign(maxSize,false);
	positiveDist[source]=newRealDist[source]=0;

	priority_queue<pair<int,int>>heap;
	heap.push({0, source});

	while(!heap.empty())
	{
		int x=heap.top().second;
		heap.pop();
		if(viz[x])
			continue;
		viz[x]=true;
		for(int y:G[x])
		{
			int positiveCostXY=realDist[x]+cost[x][y]-realDist[y];
			if(!viz[y] && flow[x][y]!=cap[x][y] && positiveDist[x]+positiveCostXY<positiveDist[y])
			{
				positiveDist[y]=positiveDist[x]+positiveCostXY;
				heap.push({-positiveDist[y], y});
				newRealDist[y]=newRealDist[x]+cost[x][y];
				t[y]=x;
			}
		}
	}

	realDist=newRealDist;
}
void MaxFluxMinCost()
{
	BellmanFord();
	while(1)
	{
		Dijkstra();
		if(positiveDist[sink]==INF)
			break;
		int minFlux=1<<30;
		for(int node=sink;node!=source;node=t[node])
			minFlux=min(minFlux,cap[t[node]][node]-flow[t[node]][node]);
		minCost+=realDist[sink]*minFlux;
		maxFlux+=minFlux;
		for(int node=sink;node!=source;node=t[node])
		{
			flow[t[node]][node]+=minFlux;
			flow[node][t[node]]-=minFlux;
		}
	}
}
void AddEdge(int x, int y, int capacitate, int pret)
{
	G[x].push_back(y);
	G[y].push_back(x);
	cap[x][y]=capacitate;
	cost[x][y]=pret;
	cost[y][x]=-pret;
}

int main()
{
    freopen("cc.in","r",stdin);
    freopen("cc.out","w",stdout);
	scanf("%d",&n);
	source=0;
	sink=2*n+1;
	maxSize=sink+1;
	for(int i=1;i<=n;i++)
	{
		for(int j=n+1;j<=2*n;j++)
		{
			int c;
			scanf("%d",&c);
			AddEdge(i,j,1,c);
		}
	}
	for(int i=1;i<=n;i++)
	{
		AddEdge(source,i,1,0);
		AddEdge(n+i,sink,1,0);
	}
	MaxFluxMinCost();
	printf("%d\n",minCost);
}