Pagini recente » Cod sursa (job #2978223) | Cod sursa (job #840247) | Cod sursa (job #910206) | Cod sursa (job #1419589) | Cod sursa (job #2812417)
#include <iostream>
#include <bits/stdc++.h>
#define maxFlow 1e9
using namespace std;
ifstream in ("cuplaj.in");
ofstream out ("cuplaj.out");
struct hash_pair {
template <class T1, class T2>
size_t operator()(const pair<T1, T2>& p) const
{
auto hash1 = hash<T1>{}(p.first);
auto hash2 = hash<T2>{}(p.second);
return hash1 ^ hash2;
}
};
int n1, n2;
int n, m;
int s, f;
vector<int> la[20001];
unordered_map<pair<int,int>, int, hash_pair> fluxLeft;
int parent[20001];
int flux = 0;
void getPath()
{
memset(parent, 0, sizeof(parent));
vector<int> q;
parent[s] = -1;
q.push_back(s);
for (int i = 0; i < q.size() ; i++)
{
if (q[i] == n)
{
continue;
}
for (auto to: la[q[i]])
{
if (fluxLeft[{q[i], to}] <= 0 || parent[to] != 0)
continue;
parent[to] = q[i];
q.push_back(to);
}
}
}
int main()
{
in >> n1 >> n2 >> m;
n = n1 + n2 + 2;
s = 1; f = n;
for (int i = 1; i <= m ; ++i)
{
int x,y;
in >> x >> y;
x += 1;
y += 1 + n1;
la[x].push_back(y);
la[y].push_back(x);
fluxLeft[{x,y}] = 1;
}
// muchii de la start la nodurile din stanga
for (int i = 2; i <= n1+1; i++)
{
la[1].push_back(i);
la[i].push_back(1);
fluxLeft[{1, i}] = 1;
}
// muchii de la nodurile din dreapta la final
for (int i = n1 + 2; i <= n1 + 1 + n2; i++)
{
la[i].push_back(n1 + n2 + 2);
la[n1 + n2 + 2].push_back(i);
fluxLeft[{i, n1 + n2 + 2}] = 1;
}
getPath();
while (parent[f] != 0)
{
for (int i = -1; i < (int)la[f].size(); i++)
{
if (i != -1)
{
parent[f] = la[f][i];
}
int minn = maxFlow;
int nod = f;
while (parent[nod] != -1)
{
if (fluxLeft[{parent[nod], nod}] < minn)
minn = fluxLeft[{parent[nod], nod}];
if (minn <= 0)
break;
nod = parent[nod];
}
if (minn <= 0)
continue;
flux += minn;
nod = f;
while (parent[nod] != -1)
{
fluxLeft[{parent[nod], nod}] -= minn;
fluxLeft[{nod, parent[nod]}] += minn;
nod = parent[nod];
}
}
getPath();
}
out << flux << '\n';
for (int i = 2; i < 2 + n1; i++)
{
for (auto to: la[i])
{
if (to == 1)
continue;
if (fluxLeft[{i, to}] == 0)
out << i-1 << ' ' << to - 1 - n1 << '\n';
}
}
return 0;
}
/*
6 8
1 2 10
1 3 8
2 3 2
2 4 5
3 5 10
5 4 8
4 6 7
5 6 10
// 15
*/
/*
6 7
1 2 6
1 3 8
2 4 5
3 5 4
2 5 3
4 6 7
5 6 5
// 10
*/