Pagini recente » Cod sursa (job #2565045) | Cod sursa (job #2960481)
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream in("cuplaj.in");
ofstream out("cuplaj.out");
const int maxn = 20005;
struct muchie {
int vec;
int flux;
int cap;
};
vector <muchie> v[maxn];
int dist[maxn];
int tata[maxn];
int sursa, destinatie;
queue <int> q;
int n;
int cautbin(int x, int y)
{
int st = 0;
int dr = v[x].size() - 1;
while(st <= dr)
{
int mij = (st + dr) / 2;
if(v[x][mij].vec < y)
st = mij + 1;
else if(v[x][mij].vec > y)
dr = mij - 1;
else
return mij;
}
return -1;
}
int gasiremuchie(int x, int y) /// gaseste indicele muchiei (x, y), returneaza -1 daca nu exista
{
if(v[x].size() >= 100)
return cautbin(x, y);
for(int i = 0; i < v[x].size(); i++)
if(v[x][i].vec == y)
return i;
return -1;
}
bool bfs()
{
for(int i = 1; i <= n; i++)
dist[i] = (1 << 30);
dist[sursa] = 0;
q.push(sursa);
while(!q.empty())
{
int nod = q.front();
q.pop();
if(nod == destinatie)
continue;
for(auto m : v[nod])
{
if(dist[m.vec] > dist[nod] + 1 && m.flux < m.cap)
{
dist[m.vec] = dist[nod] + 1;
tata[m.vec] = nod;
q.push(m.vec);
}
}
}
if(dist[destinatie] == (1 << 30))
return 0;
return 1;
}
vector <pair <int, int> > input;
inline bool cmp(muchie a, muchie b)
{
return a.vec < b.vec;
}
int main()
{
int m, e;
in >> n >> m >> e;
int ninit = n;
sursa = n + m + 1;
destinatie = n + m + 2;
for(int i = 1; i <= e; i++)
{
int x, y;
in >> x >> y;
v[x].push_back({y + n, 0, 1});
v[y + n].push_back({x, 0, 0});
input.push_back(make_pair(x, y));
}
for(int i = 1; i <= n; i++)
{
v[sursa].push_back({i, 0, 1});
v[i].push_back({sursa, 0, 0});
}
for(int i = 1; i <= m; i++)
{
v[i + n].push_back({destinatie, 0, 1});
v[destinatie].push_back({i + n, 0, 0});
}
n = n + m + 2;
for(int i = 1; i <= n; i++)
sort(v[i].begin(), v[i].end(), cmp);
while(bfs())
{
for(auto it : v[destinatie])
{
int col = gasiremuchie(it.vec, destinatie);
if(dist[it.vec] == (1 << 30) || v[it.vec][col].flux == v[it.vec][col].cap)
continue;
tata[destinatie] = it.vec;
int act = destinatie;
vector <int> drum;
while(tata[act] != 0)
{
drum.push_back(act);
act = tata[act];
}
drum.push_back(act);
reverse(drum.begin(), drum.end());
int topush = (1 << 30);
for(int i = 0; i < drum.size() - 1; i++)
{
int aux = gasiremuchie(drum[i], drum[i + 1]);
topush = min(topush, v[drum[i]][aux].cap - v[drum[i]][aux].flux);
}
for(int i = 0; i < drum.size() - 1; i++)
{
v[drum[i]][gasiremuchie(drum[i], drum[i + 1])].flux += topush;
v[drum[i + 1]][gasiremuchie(drum[i + 1], drum[i])].flux -= topush;
}
}
}
int sol = 0;
for(auto it : v[sursa])
sol = sol + it.flux;
out << sol << "\n";
//for(auto it : v[1])
//cout << it.vec << " " << it.flux << " " << it.cap << "\n";
for(auto it : input)
if(v[it.first][gasiremuchie(it.first, it.second + ninit)].flux == 1)
out << it.first << " " << it.second << "\n";
return 0;
}