Pagini recente » Cod sursa (job #2176900) | Cod sursa (job #2386165) | Cod sursa (job #3253203) | Cod sursa (job #159683) | Cod sursa (job #3202153)
#include <bits/stdc++.h>
#ifdef LOCAL
#define in cin
#define out cout
#endif
using namespace std;
#ifndef LOCAL
ifstream in("cc.in");
ofstream out("cc.out");
#endif
const int nmax = 207;
const int inf = 2e9;
int s, d;
int cntE = 0;
int pi[nmax];
int dist[nmax];
vector<int> adj[nmax];
int enter[nmax];
struct edge
{
int fr, to, c, w;
edge(int fr = 0, int to = 0, int c = 0, int w = 0) : fr(fr), to(to), c(c), w(w) {}
int rw()
{
return pi[fr] - pi[to] + w;
}
} edges[nmax * nmax * 2];
void resetDist()
{
for (int i = s; i <= d; i++)
{
dist[i] = inf;
}
}
void toPi()
{
for (int i = s; i <= d; i++)
{
pi[i] += dist[i];
}
}
bool dijkstra()
{
struct dijelem
{
int a, b;
dijelem(int a, int b) : a(a), b(b) {}
bool operator<(const dijelem &other) const
{
return b > other.b;
}
};
priority_queue<dijelem> pq;
pq.push({s, 0});
resetDist();
dist[s] = 0;
while (!pq.empty())
{
auto node = pq.top();
pq.pop();
for (auto i : adj[node.a])
{
if (edges[i].c == 0)
continue;
int to = edges[i].to;
if (dist[to] > dist[node.a] + edges[i].rw())
{
dist[to] = dist[node.a] + edges[i].rw();
enter[to] = i;
pq.push({to, dist[to]});
}
}
}
if (dist[d] == inf)
return 0;
toPi();
return 1;
}
void addE(int fr, int to, int c, int w)
{
edges[cntE] = {fr, to, c, w};
edges[cntE + 1] = {to, fr, 0, -w};
adj[fr].push_back(cntE);
adj[to].push_back(cntE + 1);
cntE += 2;
}
void dfs(int node, int &cst)
{
if (node == s)
return;
int ind = enter[node];
cst += edges[ind].w;
edges[ind].c -= 1;
edges[ind ^ 1].c += 1;
dfs(edges[ind].fr, cst);
}
int main()
{
int n;
in >> n;
s = 0;
d = n * 2 + 1;
for (int i = 1; i <= n; i++)
{
addE(s, i, 1, 0);
}
for (int i = n + 1; i <= 2 * n; i++)
{
addE(i, d, 1, 0);
}
for (int i = 1; i <= n; i++)
{
for (int j = n + 1; j <= 2 * n; j++)
{
int w;
cin >> w;
addE(i, j, 1, w);
}
}
int res = 0;
while (dijkstra())
{
int cst = 0;
dfs(d, cst);
res += cst;
}
out << res;
}