Pagini recente » Cod sursa (job #3255871) | Cod sursa (job #1780963) | Solutii preONI 2007, Runda 3 | Cod sursa (job #78874) | Cod sursa (job #3190468)
#include <iostream>
#include <climits>
#include <queue>
#include <vector>
void IO(const std::string& a_s)
{
std::cin.tie(0)->sync_with_stdio(0);
freopen((a_s + ".in").c_str(), "r", stdin);
freopen((a_s + ".out").c_str(), "w", stdout);
}
template <typename T>
T read()
{
T temp{};
std::cin >> temp;
return temp;
}
class Graph
{
std::vector<std::vector<int>> m_edges{};
std::vector<int> m_dad{};
std::vector<bool> m_visited{};
std::vector<std::vector<int>> m_capacity{};
std::vector<std::vector<int>> m_flow{};
int m_total;
void init(int a_n, int a_src, int a_dst)
{
for (int i = 1; i <= a_n; ++i)
{
int x{ read<int>() };
int y{ read<int>() };
m_total += y;
m_capacity[a_src][i] = x;
m_capacity[a_n + i][a_dst] = y;
m_edges[a_src].push_back(i);
m_edges[i].push_back(a_src);
m_edges[a_dst].push_back(a_n + i);
m_edges[a_n + i].push_back(a_dst);
}
for (int i = 1; i <= a_n; ++i)
{
for (int j = 1; j <= a_n; ++j)
{
if (i != j)
{
m_capacity[i][a_n + j] = 1;
m_edges[i].push_back(a_n + j);
m_edges[a_n + j].push_back(i);
}
}
}
}
void bfs(int a_src, int a_dst)
{
m_visited.assign(a_dst + 1, false);
std::queue<int> q{};
q.push(a_src);
m_visited[a_src] = true;
m_dad[a_src] = 0;
while (!q.empty())
{
int curr_node{ q.front() };
q.pop();
if (curr_node == a_dst)
{
continue;
}
for (int next_node : m_edges[curr_node])
{
if (!m_visited[next_node] && m_capacity[curr_node][next_node] != m_flow[curr_node][next_node])
{
m_visited[next_node] = true;
m_dad[next_node] = curr_node;
q.push(next_node);
}
}
}
}
void flux(int a_src, int a_dst)
{
while (true)
{
bfs(a_src, a_dst);
if (!m_visited[a_dst])
{
break;
}
for (int next_node : m_edges[a_dst])
{
if (!m_visited[next_node] || m_capacity[next_node][a_dst] == m_flow[next_node][a_dst])
{
continue;
}
m_dad[a_dst] = next_node;
int min_flow{ INT_MAX };
for (int curr_node = a_dst; curr_node != a_src; curr_node = m_dad[curr_node])
{
min_flow = std::min(min_flow, m_capacity[m_dad[curr_node]][curr_node] - m_flow[m_dad[curr_node]][curr_node]);
}
if (min_flow == 0)
{
break;
}
for (int curr_node = a_dst; curr_node != a_src; curr_node = m_dad[curr_node])
{
m_flow[m_dad[curr_node]][curr_node] += min_flow;
m_flow[curr_node][m_dad[curr_node]] -= min_flow;
}
}
}
}
public:
explicit Graph(int a_n) : m_edges(2 * a_n + 2), m_dad(2 * a_n + 2), m_capacity(2 * a_n + 2), m_flow(2 * a_n + 2), m_total(0)
{
for (auto& capacity : m_capacity)
{
capacity.resize(2 * a_n + 2);
}
for (auto& flow : m_flow)
{
flow.resize(2 * a_n + 2);
}
init(a_n, 0, 2 * a_n + 1);
}
void solve(int a_n)
{
flux(0, 2 * a_n + 1);
std::cout << m_total << '\n';
for (int i = 1; i <= a_n; ++i)
{
for (int j = 1; j <= a_n; ++j)
{
if (i != j && m_capacity[i][a_n + j] == m_flow[i][a_n + j])
{
std::cout << i << ' ' << j << '\n';
}
}
}
}
};
int main()
{
IO("harta");
int n{ read<int>() };
Graph g(n);
g.solve(n);
return 0;
}