Mai intai trebuie sa te autentifici.
Cod sursa(job #3191391)
Utilizator | 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);
}