Pagini recente » Cod sursa (job #62406) | Cod sursa (job #1734232) | Cod sursa (job #1651744) | Cod sursa (job #1310808) | Cod sursa (job #2945481)
#include <fstream>
#include<vector>
#include <algorithm>
#import <cmath>
#import <cassert>
#import <queue>
using namespace std;
class flux
{
struct duo
{
int nod,val;
bool operator ()(duo a,duo b)
{
return (a.val>b.val);
}
};
vector<vector<int>>f,cap;
vector<int>t;
vector<vector<duo>>a;
int n;
vector<int>dist;
void ford(int s)
{
fill(dist.begin(),dist.end(),2e9);
dist[s]=0;
queue<duo>q;
q.push({s,0});
while(q.size())
{
auto acm=q.front();
q.pop();
if(acm.val!=dist[acm.nod])continue;
for(auto &c:a[acm.nod])
{
if(cap[acm.nod][c.nod]!=f[acm.nod][c.nod] && dist[acm.nod]+c.val<dist[c.nod])
{
dist[c.nod]=dist[acm.nod]+c.val;
q.push({c.nod,dist[c.nod]});
}
}
}
}
vector<int>real,lie;
bool dij(int s,int d)
{
fill(real.begin(),real.end(),2e9);
fill(lie.begin(),lie.end(),2e9);
priority_queue<duo,vector<duo>,duo>q;
q.push({s,0});
real[s]=lie[s]=0;
while(q.size())
{
auto acm=q.top();
q.pop();
if(acm.val!=lie[acm.nod])continue;
for(auto &c:a[acm.nod])
{
if(f[acm.nod][c.nod]!=cap[acm.nod][c.nod] && acm.val+c.val+dist[acm.nod]-dist[c.nod]<lie[c.nod])
{
lie[c.nod]=acm.val+c.val+dist[acm.nod]-dist[c.nod];
real[c.nod]=real[acm.nod]+c.val;
t[c.nod]=acm.nod;
q.push({c.nod,lie[c.nod]});
}
}
}
return (real[d]!=2e9);
}
bool ford(int s,int d)
{
fill(dist.begin(),dist.end(),2e9);
dist[s]=0;
queue<duo>q;
q.push({s,0});
while(q.size())
{
auto acm=q.front();
q.pop();
if(acm.val!=dist[acm.nod])continue;
for(auto &c:a[acm.nod])
{
if(cap[acm.nod][c.nod]!=f[acm.nod][c.nod] && dist[acm.nod]+c.val<dist[c.nod])
{
t[c.nod]=acm.nod;
dist[c.nod]=dist[acm.nod]+c.val;
if(c.nod!=d)
{
q.push({c.nod,dist[c.nod]});
}
}
}
}
return (dist[d]!=2e9);
}
public:
flux(int n)
{
this->n=n;
a=vector<vector<duo>>(n+1);
f=cap=vector<vector<int>>(n+1,vector<int>(n+1,0));
t=dist=real=lie=vector<int>(n+1);
}
void add_edge(int x,int y,int cap,int cost)
{
this->cap[x][y]=cap;
a[x].push_back({y,cost});
a[y].push_back({x,-cost});
}
void init(int s)
{
ford(s);
}
int get_ans(int s,int d)
{
int rez=0;
init(s);
while(dij(s,d))
{
int val=2e9;
for(int i=d;i!=s;i=t[i])
{
val=min(val,cap[t[i]][i]-f[t[i]][i]);
}
for(int i=d;i!=s;i=t[i])
{
f[t[i]][i]+=val;
f[i][t[i]]-=val;
}
rez+=(val*real[d]);
}
return rez;
}
};
main()
{
ifstream cin("cc.in");
ofstream cout("cc.out");
int n,m,q;
cin>>n;
const int s=0,d=2*n+1;
flux solve(d+1);
for(int i=1;i<=n;i++)
{
solve.add_edge(s,i,1,0);
solve.add_edge(i+n,d,1,0);
}
for(int i=1;i<=n;i++)
{
for(int j=n+1;j<=2*n;j++)
{
int x;
cin>>x;
solve.add_edge(i,j,1,x);
}
}
cout<<solve.get_ans(s,d);
}