精明的老板
题目描述
我们经常会听到一句话:“男女搭配,干活不累。”精明的老板经过观察发现,两个男女推销员搭配工作,业务量明显高于其他人。然而并不是任何两个男女推销员都可以合作默契的,如果有的男女推销员本身有矛盾,就无法一起工作。老板了解每个员工的配合情况后,可以设计一个算法找出最佳的推销员配对方案,使每天派出的推销员最多,从而获得最大的效益。
输入
第一行是一个整型数C(C<100)表示共有C组测试数据。
每组测试数据第一行输入女推销员人数m和男推销员人数n(1<=m,n<=100)。
接下来输入可以配合的女推销员编号u和男推销员编号v(两个都为-1结束)(1<=u<=100,u<v<=200)。
输出
对于每一组输入,输出最大配对数。
每组的输出占一行。
样例输入
2
5 7
1 6
1 8
2 7
2 8
2 11
3 7
3 9
3 10
4 12
4 9
5 10
-1 -1
4 5
1 5
1 6
2 7
3 8
3 9
4 7
-1 -1
样例输出
5
3
#include<bits/stdc++.h>
#include<string>
using namespace std;
typedef long long ll;
const int mod=998244353;
const int inf=0x3f3f3f3f;
const int N=2e2+10;
struct data
{
int v;int nxt;int val;
}edge[10010];
int h[N];int cnt=1;
void add(int u,int v,int val)
{
edge[++cnt].v=v;edge[cnt].val=val;
edge[cnt].nxt=h[u];h[u]=cnt;
return;
}
int dep[N];bool book[N];
int n;int m;int res;
int s;int t;queue<int> q;
int dfs(int x,int lim)
{
if(x==t){
return lim;
}
int nxt=h[x];
while(nxt)
{
int v=edge[nxt].v;
int val=edge[nxt].val;
if(dep[v]==dep[x]+1&&val!=0)
{
int delta=dfs(v,min(val,lim));
if(delta!=0)
{
edge[nxt].val-=delta;
edge[nxt^1].val+=delta;
return delta;
}
}
nxt=edge[nxt].nxt;
}
return 0;
}
void bfs()
{
for(int i=1;i<=n+m+2;i++)
book[i]=false;
dep[s]=1;book[s]=true;
q.push(s);
while(!q.empty())
{
int now=q.front();q.pop();
int nxt=h[now];
while(nxt)
{
int v=edge[nxt].v;
int val=edge[nxt].val;
if(val!=0&&book[v]==false)
{
dep[v]=dep[now]+1;
book[v]=true;
q.push(v);
}
nxt=edge[nxt].nxt;
}
}
return;
}
int main()
{
int j;
scanf("%d",&j);
while(j--){
res=0;
memset(edge,0,sizeof(edge));
scanf("%d%d",&m,&n);
s=n+m+1;t=n+m+2;
while(1)
{
int u;int v;
scanf("%d%d",&u,&v);
if(u==-1&&v==-1)break;
add(u,v,1);add(v,u,0);
}
for(int i=1;i<=m;i++)
{
add(s,i,1);add(i,s,0);
}
for(int i=m+1;i<=m+n;i++)
{
add(i,t,1);add(t,i,0);
}
bfs();
while(book[t])
{
while(1)
{
int p=dfs(s,inf);
if(p==0)break;else res+=p;
}bfs();
}
printf("%d\n",res);
}
}