Pagini recente » Cod sursa (job #1459613) | Cod sursa (job #1695592) | Cod sursa (job #1440604) | Cod sursa (job #782104) | Cod sursa (job #2960729)
#include <iostream>
#include <fstream>
#include <list>
#include <vector>
#include <queue>
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
int leftNodesNumber, rightNodesNumber;
int edges, s, t;
vector < bool > existingRight;
vector < pair < int, int >> parent, rightNodes;
vector < vector < tuple < int, int, int >>> adjList;
void createEdge(int x, int y) {
adjList[x].emplace_back(y, 1, adjList[y].size());
adjList[y].emplace_back(x, 0, adjList[x].size() - 1);
if (y == t) {
rightNodes.emplace_back(x, adjList[x].size() - 1);
}
}
bool bfs() {
vector < bool > visited(t + 1);
queue < int > q;
q.push(s);
visited[s] = true;
parent[s] = {-1, -1};
while (!q.empty()) {
int firstInQueue = q.front();
q.pop();
if (firstInQueue == t) {
continue;
}
int i = 0;
for (auto const& node: adjList[firstInQueue]) {
auto [adjNode, capacity, reverseEdge] = node;
if (!visited[adjNode] && capacity) {
parent[adjNode] = {firstInQueue, i};
visited[adjNode] = true;
q.push(adjNode);
}
++i;
}
}
return visited[t];
}
long long cuplaj() {
long long maxFlow = 0;
while (bfs()) {
for (auto const& node: rightNodes) {
int currentFlow = 1;
parent[t] = node;
int y = t;
while (parent[y].first != -1) {
int first = parent[y].first;
int second = parent[y].second;
currentFlow = min(currentFlow, get < 0 > (adjList[first][second]));
y = second;
}
y = t;
while (parent[y].first != -1) {
int u = parent[y].first;
int v = parent[y].second;
int w = get < 2 > (adjList[u][v]);
auto [adjNode, capacity, reverseEdge] = adjList[u][v];
auto [adjNode2, capacity2, reverseEdge2] = adjList[y][w];
adjList[u][v] = {adjNode, capacity - currentFlow, reverseEdge};
adjList[y][w] = {adjNode2, capacity2 + currentFlow, reverseEdge2};
y = u;
}
maxFlow += currentFlow;
}
}
return maxFlow;
}
int main() {
f >> leftNodesNumber >> rightNodesNumber >> edges;
t = leftNodesNumber + rightNodesNumber + 1;
existingRight.resize(rightNodesNumber + 1);
parent.resize(t + 1);
adjList.resize(t + 1);
for (int i = 1; i <= leftNodesNumber; ++i) {
createEdge(s, i);
}
for (int i = 1; i <= edges; ++i) {
int x, y;
f >> x >> y;
createEdge(x, leftNodesNumber + y);
existingRight[y] = true;
}
for (int i = 1; i <= rightNodesNumber; ++i) {
if (existingRight[i]) {
createEdge(leftNodesNumber + i, t);
}
}
g << cuplaj() << '\n';
for (int i = 1; i <= leftNodesNumber; ++i) {
for (auto const& node: adjList[i]) {
auto [adjNode, capacity, reverseEdge] = node;
if (adjNode && capacity == 0 && adjNode != t) {
g << i << " " << adjNode - leftNodesNumber << '\n';
}
}
}
}