Pagini recente » Cod sursa (job #40553) | Cod sursa (job #2162498) | Cod sursa (job #3129164) | Cod sursa (job #117336) | Cod sursa (job #3189639)
#include <fstream>
#include <vector>
#include <queue>
#include <climits>
#include <map>
#include <iostream>
using namespace std;
ifstream fin("cc.in");
ofstream fout("cc.out");
struct Edge {
int to;
int flow;
int capacity;
int cost;
int reverse;
};
class Network {
int V;
int source, sink;
vector<int> parent;
vector<int> dist;
vector<vector<Edge>> adj;
public:
Network(int V, int source = -1, int sink = -1) {
this->V = V;
this->source = source == -1 ? 0 : source;
this->sink = sink == -1 ? V - 1 : sink;
adj.resize(V);
dist.resize(V, INT_MAX);
parent.resize(V, -1);
}
void addEdge(int u, int v, int capacity, int cost) {
Edge a{v, 0, capacity, cost,(int)adj[v].size()};
Edge b{u, 0, 0, -cost, (int)adj[u].size()};
adj[u].push_back(a);
adj[v].push_back(b);
}
bool dijkstra();
int DFS(int node, int bottleneck, int t);
int getMaxFlow();
int getCostForMaxFlow(int node, int flow);
};
bool Network::dijkstra() {
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
dist.assign(V, INT_MAX);
dist[source] = 0;
pq.emplace(0, source);
while (!pq.empty()) {
int currDistance = pq.top().first;
int currNode = pq.top().second;
pq.pop();
if (currDistance != dist[currNode]) continue;
for (auto &edge : adj[currNode]) {
if (edge.flow < edge.capacity && dist[currNode] != INT_MAX && dist[edge.to] > dist[currNode] + edge.cost) {
dist[edge.to] = dist[currNode] + edge.cost;
parent[edge.to] = currNode;
if (edge.to != sink) {
pq.emplace(dist[edge.to], edge.to);
}
}
}
}
return dist[sink] != INT_MAX;
}
int Network::getCostForMaxFlow(int node, int flow) {
int totalCost = 0, bottleneck = INT_MAX;
while (dijkstra()) {
for (int v = sink; v != source; v = parent[v]) {
int u = parent[v];
for(auto &edge : adj[u]){
if(edge.to == v){
bottleneck = min(bottleneck, edge.capacity - edge.flow);
break;
}
}
}
for (int v = sink; v != source; v = parent[v]) {
int u = parent[v];
for(auto &edge : adj[u]){
if(edge.to == v){
edge.flow += bottleneck;
adj[v][edge.reverse].flow -= bottleneck;
totalCost += edge.cost * bottleneck;
break;
}
}
}
}
return totalCost;
}
int main()
{
int n;
fin >> n;
int source = 2*n, sink = 2*n + 1;
Network network(2*n + 2, source, sink);
int x;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; ++j) {
fin >> x;
network.addEdge(i, j + n, 1, x);
}
}
for (int i = 0; i < n; i++) {
network.addEdge(source, i, 1, 0);
network.addEdge(i + n, sink, 1, 0);
}
fout << network.getCostForMaxFlow(0, INT_MAX) << "\n";
}