过山车
题目描述
RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了。可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做partner和她同坐。但是,每个女孩都有各自的想法。
举个例子把,Rabbit只愿意和XHD或PQK做partner,Grass只愿意和linle或LL做partner,PrincessSnow愿意和水域浪子或伪酷儿做partner。
考虑到经费问题,boss刘决定只让找到partner的人去坐过山车,其他的人,嘿嘿,就站在下面看着吧。
聪明的你,你可以帮忙算算最多有多少对组合可以坐上过山车吗?
输入格式
第一行是三个整数K , M , N,分别表示可能的组合数目,女生的人数,男生的人数。0<K<=1000
1<=N 和 M<=500。
接下来的K行,每行有两个数,分别表示女生Ai愿意和男生Bj做partner。
输出格式
输出一个整数,表示可以坐上过山车的最多组合数。
样例输入1
6 3 3
1 1
1 2
1 3
2 1
2 3
3 1
样例输出1
3
注释说明
对于100%的数据,0<K<=1000,1<=N,M<=500
#include<bits/stdc++.h>
using namespace std;
const int M=5015,N=5015;
int n,m,gi,bo,ans,pre[N],k=1,s=1005,t=1004;
int dep[N];
struct ed{
int to,w,nxt;
}e[N*2];
void add(int u,int v,int w)
{
e[++k]=(ed){v,w,pre[u]};
pre[u]=k;
}
bool bfs()
{ //puts("o");
memset(dep,-1,sizeof(dep));
queue<int>q;
dep[s]=1;
q.push(s);
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=pre[x];i;i=e[i].nxt ){
int w=e[i].w,to=e[i].to;
if(w>0&&dep[to]==-1)
{
dep[to]=dep[x]+1;
if(to==t)
{
return 1;
}
q.push(to);
}
}
}
// for(int i=1;i<=gi+bo;i++)printf("%d ",dep[i]);puts("");
return 0;
}
int dfs(int x,int c)
{
if(x==t)return c;
int f=0;
for(int i=pre[x];i&&f<c;i=e[i].nxt )
{
int to=e[i].to,w=e[i].w ;
if(w>0&&dep[to]==dep[x]+1)
{
int y=dfs(to,min(c-f,w));
f+=y;
e[i].w-=y;
e[i^1].w+=y;
}
}
if(f==0)dep[x]=-2;
return f;
}
signed main()
{
scanf("%d%d%d",&m,&gi,&bo);
int u,v;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
v+=500;
add(u,v,1);
add(v,u,0);
}
for(int i=1;i<=gi;i++)
{
add(s,i,1);
add(i,s,0);
}
for(int i=1;i<=bo;i++)
{
int o=i+500;
add(o,t,1);
add(t,o,0);
}
while(bfs())
{
ans+=dfs(s,0x7f7f7f7f);
// printf("ans%d\n",ans);
}
printf("%d\n",ans);
}