Pagini recente » Monitorul de evaluare | Cod sursa (job #3284043) | Cod sursa (job #2716856) | Cod sursa (job #200565) | Cod sursa (job #3193514)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <limits.h>
const int INF = INT_MAX;
std::vector<std::vector<int>> adj_list, cost, capacity;
void shortest_paths(int n, int v0, std::vector<int>& d, std::vector<int>& p)
{
d.assign(n, INF);
d[v0] = 0;
std::vector<bool> inq(n, false);
std::queue<int> q;
q.push(v0);
p.assign(n, -1);
while(!q.empty())
{
int u = q.front();
q.pop();
inq[u] = false;
for(int v: adj_list[u])
{
if(capacity[u][v] > 0 && d[v] > d[u] + cost[u][v])
{
d[v] = d[u] + cost[u][v];
p[v] = u;
if(!inq[v])
{
inq[v] = true;
q.push(v);
}
}
}
}
}
std::pair<int, int> min_cost_flow(int n, int s, int t, int k = INF)
{
int flow = 0;
int cost = 0;
std::vector<int> d, p;
while(flow < k)
{
shortest_paths(n, s, d, p);
if(d[t] == INF)
break;
int f = k - flow;
int node = t;
while(node != s)
{
f = std::min(f, capacity[p[node]][node]);
node = p[node];
}
flow += f;
cost += f * d[t];
node = t;
while(node != s)
{
capacity[p[node]][node] -= f;
capacity[node][p[node]] += f;
node = p[node];
}
}
return {flow, cost};
}
int main()
{
std::ifstream f("cc.in");
std::ofstream g("cc.out");
int n_=0;
f >> n_;
int n = 2*n_ + 2;
int s = 0, t = 2*n_ +1;
adj_list.assign(n, std::vector<int>());
cost.assign(n, std::vector<int>(n, 0));
capacity.assign(n, std::vector<int>(n, 0));
int dist = 0;
for(int i=1;i<=n_;i++)
for(int j=1;j<=n_;j++)
{
f >> dist;
adj_list[i].push_back(n_+j);
adj_list[n_+j].push_back(i);
cost[i][n_+j] = dist;
cost[n_+j][i] = -dist;
capacity[i][n_+j] = 1;
}
for(int i=1;i<=n_;i++)
{
adj_list[s].push_back(i);
adj_list[i].push_back(s);
capacity[s][i] = 1;
}
for(int i=1;i<=n_;i++)
{
adj_list[n_+i].push_back(t);
adj_list[t].push_back(n_+i);
capacity[n_+i][t] = 1;
}
auto rez = min_cost_flow(n, s, t);
g << rez.second;
f.close();
g.close();
return 0;
}