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结束输入。 Output 对于每组数据,输出一个整数,表示可以坐上过山车的最多组合数。 Sample Input
6 3 3 1 1 1 2 1 3 2 1 2 3 3 1 0Sample Output
3
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define all(x) begin(x),end(x)
ll rd(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct AA
{
int from;
int to;
int weight;
AA(){}
AA(int f, int t, int w):from(f), to(t), weight(w) {}
};
const int __maxNodes=1e3+10;
vector<int> G[__maxNodes]; /* G[i] 存储顶点 i 出发的边的编号 */
vector<AA> edges;
typedef vector<int>::iterator iterator_t;
int num_nodes;
int num_left;
int num_right;
int num_edges;
queue<int> Q;
int pre[__maxNodes];
int matching[__maxNodes];
int check[__maxNodes];
int Hungarian()
{
int ans = 0;
memset(matching, -1, sizeof(matching));
memset(check, -1, sizeof(check));
for (int i=0; i<num_left; ++i) {
if (matching[i] == -1) {
while (!Q.empty()) Q.pop();
Q.push(i);
//cout<<i<<endl;
pre[i] = -1; // 设 i 为路径起点
bool flag = false; // 尚未找到增广路
while (!Q.empty() && !flag) {
int u = Q.front();
for (iterator_t ix = G[u].begin(); ix != G[u].end() && !flag; ++ix) {
int v = edges[*ix].to;
if (check[v] != i) {
check[v] = i;
Q.push(matching[v]);
if (matching[v] >= 0) { // 此点为匹配点
pre[matching[v]] = u;
} else { // 找到未匹配点,交替路变为增广路
flag = true;
int d=u, e=v;
while (d != -1) {
int t = matching[d];
matching[d] = e;
matching[e] = d;
d = pre[d];
e = t;
}
}
}
}
Q.pop();
}
if (matching[i] != -1) ++ans;
}
}
return ans;
}
int main()
{
int k,m,n;
freopen("in.txt","r",stdin);
while(scanf("%d",&k)){
if(k==0)return 0;
m=rd(),n=rd();
for(int i=0;i<=m+n;i++)
G[i].clear();
num_left=m;
edges.clear();
edges.resize(k);
for(int i=0;i<k;i++){
int x=rd()-1,y=rd()+m-1;
edges[i]=AA{x,y,1};
G[x].push_back(i);
}
//cout<<Hungarian()<<endl;
printf("%d\n",Hungarian());
}
return 0;
}