Pagini recente » Cod sursa (job #2956930) | Cod sursa (job #2830253) | Cod sursa (job #358140) | Cod sursa (job #2354895) | Cod sursa (job #3186126)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <climits>
using namespace std;
ifstream f("cc.in");
ofstream g("cc.out");
int N, S, T, dist;
vector<vector<int>> list, cap, flow, distanta;
vector<int> previous, distantaMin;
int res;
void citire_date () {
f>>N;
T = 2*N+1;
previous.resize(T+1);
distantaMin.resize(T+1);
list.resize(T+1, {});
cap.assign(T+1, vector<int>(T+1, 0));
flow.resize(T+1, vector<int>(T+1, 0));
distanta.resize(T+1, vector<int>(T+1, 0));
for (int i=1; i<=N; i++) {
list[0].push_back(i);
list[i].push_back(0);
cap[0][i] = 1;
for (int j=1; j<=N; j++) {
f>>dist;
list[i].push_back(j+N);
list[j+N].push_back(i);
cap[i][j+N] = 1;
distanta[i][j+N] = dist;
distanta[j+N][i] = -dist;
}
}
for (int i=1; i<=N; i++) {
list[i+N].push_back(T);
list[T].push_back(i+N);
cap[i+N][T] = 1;
}
}
void init_previous () {
for (int i=0; i<=T; i++) {
previous[i] = -1;
distantaMin[i] = INT_MAX;
}
distantaMin[0] = 0;
}
int bfs () {
// gasim un drum de la S la T
init_previous();
queue<pair<int, int>> q;
q.push({0, INT_MAX});
while (!q.empty()) {
int cur = q.front().first, minFlowUntilNow = q.front().second;
q.pop();
for (auto& next : list[cur]) {
if (distantaMin[next] > distantaMin[cur] + distanta[cur][next] && cap[cur][next] > flow[cur][next]) {
previous[next] = cur;
int residual_cap = cap[cur][next] - flow[cur][next];
int nextMinFlow = residual_cap > minFlowUntilNow ? minFlowUntilNow : residual_cap;
distantaMin[next] = distantaMin[cur] + distanta[cur][next];
q.push({next, nextMinFlow});
}
}
}
return previous[T] >= 0;
}
void edmonds_karp () {
while (true) {
int flow_of_path = bfs();
if (!flow_of_path) break; // nu a fost gasit niciun augmented path (de la S la T)
// in cazul in care a fost gasit, refacem drumul si updatam flow-ul pe tot drumul
int cur = T;
while (cur != 0) {
int prevNode = previous[cur];
flow[prevNode][cur] += flow_of_path;
flow[cur][prevNode] -= flow_of_path;
cur = prevNode;
}
res += distantaMin[T];
}
g << res;
}
void rezolvare () {
citire_date();
edmonds_karp();
}
int main () {
rezolvare();
return 0;
}