题目链接:过山车
RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了。可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做partner和她同坐。但是,每个女孩都有各自的想法,举个例子把,Rabbit只愿意和XHD或PQK做partner,Grass只愿意和linle或LL做partner,PrincessSnow愿意和水域浪子或伪酷儿做partner。考虑到经费问题,boss刘决定只让找到partner的人去坐过山车,其他的人,嘿嘿,就站在下面看着吧。聪明的Acmer,你可以帮忙算算最多有多少对组合可以坐上过山车吗?
Input
输入数据的第一行是三个整数K , M , N,分别表示可能的组合数目,女生的人数,男生的人数。0<K<=1000
1<=N 和M<=500.接下来的K行,每行有两个数,分别表示女生Ai愿意和男生Bj做partner。最后一个0结束输入。
1<=N 和M<=500.接下来的K行,每行有两个数,分别表示女生Ai愿意和男生Bj做partner。最后一个0结束输入。
Output
对于每组数据,输出一个整数,表示可以坐上过山车的最多组合数。
最大流裸题,首先起点0连接女生,然后男生连终点t,最后女生连男生,每条边限流为1,求最大流
AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define MAXN 10010
#define INF 0x3f3f3f3f
using namespace std;
struct Edge
{
int to,next,f;
}e[30000];
int first[MAXN];
int cc;
int dis[MAXN],vis[MAXN];
int s,t;
void add_edge(int u,int v,int f)
{
e[cc].to=v;
e[cc].next=first[u];
e[cc].f=f;
first[u]=cc; //以u开始的边的数量
cc++;
e[cc].to=u;
e[cc].next=first[v];
e[cc].f=0;
first[v]=cc;
cc++;
}
bool BFS()
{
memset(vis,0,sizeof(vis));
queue<int> q;
q.push(s);
dis[s]=0;
vis[s]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=first[u];i!=-1;i=e[i].next)
{
if(!vis[e[i].to]&&e[i].f>0)
{
vis[e[i].to]=1;
dis[e[i].to]=dis[u]+1;
q.push(e[i].to);
}
}
}
return vis[t];
}
int DFS(int x,int a)
{
if(x==t||a==0)
return a;
int flow=0,f;
for(int i = first[x]; i!=-1; i = e[i].next)
{
if(dis[x]+1==dis[e[i].to]&&e[i].f>0)
{
f=DFS(e[i].to,min(a-flow,e[i].f));
e[i].f-=f;
e[i^1].f+=f;
flow+=f;
if(flow==a)
return flow;
}
}
if(flow==0)
dis[x]=0;
return flow;
}
int Dinic(int s,int t)
{
int flow=0;
while(BFS())
{
flow+=DFS(s,INF);
}
return flow;
}
int main()
{
int K,M,N;
while(scanf("%d",&K)&&K!=0)
{
memset(first,-1,sizeof(first));
cc=0;
scanf("%d %d",&M,&N);
s=0,t=M+N+1;
for(int i=1;i<=M;i++)
{
add_edge(0,i,1);
}
for(int i=1;i<=N;i++)
{
add_edge(M+i,t,1);
}
int a,b;
for(int i=0;i<K;i++)
{
scanf("%d %d",&a,&b);
add_edge(a,M+b,1);
}
printf("%d\n",Dinic(s,t));
}
return 0;
}