Pagini recente » Monitorul de evaluare | Cod sursa (job #2976108) | Cod sursa (job #559676) | Cod sursa (job #1915470) | Cod sursa (job #741461)
Cod sursa(job #741461)
#include <queue>
#include <vector>
#include <fstream>
#include <cstdlib>
#include <iterator>
#include <algorithm>
using namespace std;
const int oo=1<<29;
const int N_MAX=10011;
struct vertex {
int y, capacity, flux, opusIndex;
vertex(int _y=-1, int _capacity=0): y(_y), capacity(_capacity), flux(0), opusIndex(-1) {}
};
struct pr {
int x, y;
pr(int _x=0, int _y=0) : x(_x), y(_y) {}
};
inline ostream& operator<<(ostream& out, const pr& x)
{
out<<x.x<<' '<<x.y;
return out;
}
ofstream out("cuplaj.out");
int f[2*N_MAX];
queue<int> Q;
vector<vertex> G[N_MAX];
vector<pr> match;
vector<vertex>::iterator it, iend;
vector<vertex>::iterator index[N_MAX];
int Dinic(const int& source, const int& sink, const int& N)
{
int x, y, c, s;
fill(f, f+sink+1, -1);
f[source]=0;
for(Q.push(source); !Q.empty(); Q.pop())
{
x=Q.front();
if(sink == x)
continue;
for(it=G[x].begin(), iend=G[x].end(); it < iend; ++it)
if(-1 == f[it->y] && it->capacity > it->flux)
{
f[it->y]=x;
index[it->y]=it;
Q.push(it->y);
}
}
if(-1 == f[sink])
return 0;
for(it=G[sink].begin(), iend=G[sink].end(), s=c=0; it < iend; ++it, s+=c)
if(-1 !=f[it->y])
{
index[sink]=G[it->y].begin()+it->opusIndex;
f[sink]=it->y;
c=oo;
for(y=sink; y != f[y]; y=f[y])
if(c > index[y]->capacity-index[y]->flux)
{
c=index[y]->capacity-index[y]->flux;
}
for(y=sink; y != f[y]; y=f[y])
{
index[y]->flux+=c;
G[y][index[y]->opusIndex].flux-=c;
}
}
return s;
}
int main()
{
int N, M, E, x, y, sink;
ifstream in("cuplaj.in");
for(in>>N>>M>>E; E; --E)
{
in>>x>>y;
y+=N;
G[x].push_back(vertex(y, 1));
G[y].push_back(vertex(x, 0));
G[x].back().opusIndex=G[y].size()-1;
G[y].back().opusIndex=G[x].size()-1;
}
for(x=1; x <= N; ++x)
{
G[0].push_back(vertex(x, 1));
G[x].push_back(vertex(0, 0));
G[0].back().opusIndex=G[x].size()-1;
G[x].back().opusIndex=G[0].size()-1;
}
sink=M+N+1;
for(M=sink-1; x <= M; ++x)
{
G[x].push_back(vertex(sink, 1));
G[sink].push_back(vertex(x, 0));
G[x].back().opusIndex=G[sink].size()-1;
G[sink].back().opusIndex=G[x].size()-1;
}
while(Dinic(0, sink, N));
for(x=1; x <= N; ++x)
{
for(it=G[x].begin(), iend=G[x].end(); it < iend; ++it)
if(it->flux > 0)
{
match.push_back(pr(x, it->y-N));
break;
}
}
out<<match.size()<<'\n';
copy(match.begin(), match.end(), ostream_iterator<pr>(out, "\n") );
return EXIT_SUCCESS;
}