Pagini recente » Cod sursa (job #3173472) | Cod sursa (job #816752) | Cod sursa (job #388358) | Cod sursa (job #1778392) | Cod sursa (job #2223273)
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 205;
int source = 0;
int target = MAXN-1;
int n;
int currentFlow[MAXN][MAXN];
int capacity[MAXN][MAXN];
int cost[MAXN][MAXN];
int potential[MAXN];
int distances[MAXN];
int father[MAXN];
vector< int > gr[MAXN];
class cmp {
public:
const bool operator()(const pair< int, int > &a, const pair< int, int > &b) const {
return a.second > b.second;
}
};
bool moreFlow() {
priority_queue< pair< int, int >, vector< pair< int, int > >, cmp > H;
H.push(make_pair(source, 0));
memset(distances, 0x3f, sizeof distances);
memset(father, 0, sizeof father);
distances[source] = 0;
while(H.size()) {
int node, currentCost;
tie(node, currentCost) = H.top();
H.pop();
if(distances[node] != currentCost) continue;
for(auto x : gr[node]) {
if(currentFlow[node][x] < capacity[node][x]) {
if(distances[x] > currentCost + cost[node][x] + potential[node] - potential[x]) {
distances[x] = currentCost + cost[node][x] + potential[node] - potential[x];
father[x] = node;
H.push(make_pair(x, distances[x]));
}
}
}
}
memcpy(potential, distances, sizeof potential);
return (father[target] != 0);
}
int main() {
ios::sync_with_stdio(false);
ifstream f("cc.in");
ofstream g("cc.out");
f >> n;
for(int i = 1; i <= n; ++i) {
for(int j = n+1; j <= 2*n; ++j) {
f >> cost[i][j];
gr[i].emplace_back(j);
gr[j].emplace_back(i);
cost[j][i] = -cost[i][j];
capacity[i][j] = 1;
}
}
gr[source].resize(n);
for(int i = 0; i < n; ++i) {
gr[source][i] = i+1;
capacity[source][i+1] = 1;
gr[i+1].emplace_back(source);
}
gr[target].resize(n);
for(int i = 0; i < n; ++i) {
gr[target][i] = n+i+1;
capacity[n+i+1][target] = 1;
gr[n+i+1].emplace_back(target);
}
while(moreFlow()) {
int node = target;
int minFlow = static_cast<int>(1e9);
while(node) {
minFlow = min(minFlow, capacity[father[node]][node] - currentFlow[father[node]][node]);
node = father[node];
}
node = target;
while(node) {
currentFlow[father[node]][node] += minFlow;
currentFlow[node][father[node]] -= minFlow;
node = father[node];
}
}
int ans = 0;
int cnt = 0;
for(int i = 1; i <= n; ++i) {
for(int j = n+1; j <= 2*n; ++j) {
if(currentFlow[i][j]) {
++cnt;
ans += cost[i][j];
break;
}
}
}
assert(cnt == n);
g << ans;
return 0;
}