网络流学习1 精明的老板

精明的老板

题目描述
我们经常会听到一句话:“男女搭配,干活不累。”精明的老板经过观察发现,两个男女推销员搭配工作,业务量明显高于其他人。然而并不是任何两个男女推销员都可以合作默契的,如果有的男女推销员本身有矛盾,就无法一起工作。老板了解每个员工的配合情况后,可以设计一个算法找出最佳的推销员配对方案,使每天派出的推销员最多,从而获得最大的效益。
输入
第一行是一个整型数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);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值