Pagini recente » Cod sursa (job #1269872) | Cod sursa (job #96612) | Cod sursa (job #1539628) | Cod sursa (job #1377265) | Cod sursa (job #1393531)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
ifstream F("cuplaj.in");
ofstream G("cuplaj.out");
const int N = 20010;
const int M = 120010;
struct edge {
int x,y,c[2];
int _(int xx)
{
return x+y-xx;
}
int w(int xx,int yy)
{
return ( xx == x && yy == y ) ? 0 : 1;
}
int cap(int xx,int yy)
{
return w(xx,yy) == 0 ? c[0] : c[1];
}
};
vector<int> v[N];
edge e[M];
int n,m,m2,flow,dad[N],pl[N];
int go(int x)
{
memset(dad,0,sizeof(dad));
memset(pl,0,sizeof(pl));
dad[1] = -1;
queue<int> q;
q.push( 1 );
while ( !q.empty() )
{
int x = q.front();
q.pop();
for (int i=0;i<int(v[x].size());++i)
{
int idx = v[x][i];
int y = e[idx]._(x);
if ( dad[ y ] == 0 && e[idx].cap(x,y) > 0 )
{
dad[ y ] = x;
pl[ y ] = idx;
q.push( y );
}
}
}
return dad[n] != 0;
}
int n1,n2;
int left_edge(int x)
{
return 1 + x;
}
int right_edge(int x)
{
return 1 + x + n1;
}
int rev_left_edge(int x)
{
return x-1;
}
int rev_right_edge(int x)
{
return x-1-n1;
}
int main()
{
F>>n1>>n2>>m;
for (int i=1;i<=m;++i)
{
F>>e[i].x>>e[i].y;
e[i].c[0] = 1;
e[i].x = left_edge(e[i].x);
e[i].y = right_edge(e[i].y);
v[ e[i].x ].push_back( i );
v[ e[i].y ].push_back( i );
}
n = 1 + n1 + n2 + 1;
m2 = m;
for (int i=1;i<=n1;++i)
{
e[++m].x = 1;
e[m].y = left_edge(i);
e[m].c[0] = 1;
v[ e[m].x ].push_back( m );
v[ e[m].y ].push_back( m );
}
for (int i=1;i<=n2;++i)
{
e[++m].x = right_edge(i);
e[m].y = n;
e[m].c[0] = 1;
v[ e[m].x ].push_back( m );
v[ e[m].y ].push_back( m );
}
//go(1); for (int i=1;i<=n;++i) cerr<<dad[i]<<' ';cerr<<'\n';
//for (int i=1;i<=n;++i) cerr<<pl[i]<<' ';cerr<<'\n';
while ( go(1) )
for (int i=0;i<int(v[n].size());++i)
{
int idx = v[n][i];
int x = e[idx]._(n);
//cerr<<e[idx].cap(x,n) <<'\n';
if ( dad[x] != 0 && e[idx].cap(x,n) > 0 )
{
int cap = e[idx].cap(x,n);
for (int i=x;i!=1;i=dad[i])
{
cap = min(cap,e[pl[i]].cap(dad[i],i));
if ( cap == 0 ) break;
}
if ( cap == 0 ) break;
for (int i=x;i!=1;i=dad[i])
{
int j = e[pl[i]].w(dad[i],i);
// cerr<<j<<'\n';
e[pl[i]].c[j] -= cap;
e[pl[i]].c[1-j] += cap;
}
int j = e[idx].w(x,n);
e[idx].c[j] -= cap;
flow += cap;
}
}
G<<flow<<'\n';
for (int i=1;i<=m2;++i)
if ( e[i].c[0] == 0 )
{
//cerr<<e[i].x<<' '<<e[i].y<<'\n';
G<<rev_left_edge(e[i].x)<<' '<<rev_right_edge(e[i].y)<<'\n';
}
}