POJ3281 dining——最大流(建图是重点)

题目链接点击打开链接

最大流题目多起点多聚点类型,要加一个最原始的起点和聚点。本题由于一个牛对应一种食物和水搭配,因此要添加牛x-->牛x的容量为1的路径,否则就会出现一牛对应多条路径的情况。至于点的标号。0是原始起点,1——f 表示food,f+1——2n表示牛,f+2n+1——f+2n+d表示drink f+2n+d+1 表示终点,一共f+2n+d+1 +1 个点。

AC代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<stack>
typedef long long ll;
#define pi acos(-1)
#define eps 1e-6;
using namespace std;
const int inf=1<<28;
const int maxn=405;
int mp[maxn][maxn],path[maxn],flow[maxn],sta,ed,n;

int bfs()
{
    int i,tmp;
    memset(path,-1,sizeof(path));
    queue<int> q;
    path[sta]=0,flow[sta]=inf;
    q.push(sta);
    while(!q.empty())
    {
        tmp=q.front();
        q.pop();
        if(tmp==ed) break;
        for(i=1; i<=n; i++)
        {
            if(path[i]==-1 && i!=sta && mp[tmp][i])
            {
                flow[i]=min(mp[tmp][i],flow[tmp]);
                path[i]=tmp;
                q.push(i);
            }
        }
    }
    if(path[ed]==-1) return -1;
    return flow[ed];

}
int EK()
{
    int max_flow=0,step,now,pre;
    while((step=bfs()) != -1)
    {
        max_flow+=step;
        now=ed;
        while(now!=sta)
        {
            pre=path[now];
            mp[pre][now]-=step;
            mp[now][pre]+=step;
            now=pre;
        }

    }
    return max_flow;
}
int main()
{
    int f,d,i,ff,dd,food,drink;
    while(~scanf("%d%d%d",&n,&f,&d))
    {
        memset(mp,0,sizeof(mp));
        sta=0,ed=2*n+f+d+1;
        for(i=1; i<=f; i++)  mp[0][i] = 1; ///start to food
        for(i=1; i<=d; i++) mp[2*n+f+i][ed] = 1; ///drink to end
        for(i=1; i<=n; i++) mp[f+i][f+i+n] = 1; ///cow to cow

        for(i=1; i<=n; i++)
        {
            scanf("%d%d",&ff,&dd);
            while(ff--) 
            {
                scanf("%d",&food);
                mp[food][i+f] = 1;///drink to cow
            }
            while(dd--)
            {
                scanf("%d",&drink);
                mp[n+f+i][2*n+f+drink] = 1;///cow to drink

            }
        }
        n=ed+1;/// the count of point
        printf("%d\n",EK());
    }

    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值