http://poj.org/problem?id=3281

67 篇文章 0 订阅
43 篇文章 0 订阅

我的最大流的第二题,,,话说刚学网络流,,用了最常用的算法E_k算法还调试了一会,,,,杯具啊,,看了网上大牛们的解题报告,用的都是Dinci和ISPA,,,很是神奇啊,,看来是得学学了,,,这道题难在建图上,,,为了保证每种食物,和饮料只对应一头牛,用了拆点,,,建图顺序为源点-食物-牛-牛-饮料-汇点,,每个弧的容量为1,做完这题我明白了为什么最大二分匹配可以用网络流来做了,,嘎嘎,,,

#include<iostream>
#include<cstdio>
#include<limits.h>
#include<algorithm>
#include<queue>
#define M  405
#include<string.h>
using namespace std;
int map[M][M];
int N,F,D;
void E_k(int s,int t)
{  int flow[M][M],f[M],pre[M],flowmax=0;
   queue<int> Q;
    memset(flow,0,sizeof(flow));
     while(1)
     {    Q.push(s);
      memset(f,0,sizeof(f));
         f[s]=INT_MAX;
         while(!Q.empty())
         {  int u=Q.front();
             Q.pop();
             for(int i=s;i<=t;++i)
                if(!f[i]&&map[u][i]>flow[u][i])
                  {  Q.push(i);
                    f[i]=min(f[u],map[u][i]-flow[u][i]); 
                    pre[i]=u;
                   }
           }
           if(!f[t]) break;
           for(int i=t;i!=s;i=pre[i])
             { flow[pre[i]][i]+=f[t];
               flow[i][pre[i]]-=f[t];
              }
             flowmax+=f[t];
    }
             printf("%d\n",flowmax);
}
int main()
{   while(~scanf("%d%d%d",&N,&F,&D))
    {  memset(map,0,sizeof(map));
        int a,b;
       for(int i=1;i<=N;++i)
       {  scanf("%d%d",&a,&b);
          map[i][N+i]=1;
          while(a--)
          { int c;
            scanf("%d",&c);
            map[2*N+c][i]=1;
          }
          while(b--)
          { int c;
             scanf("%d",&c);
             map[N+i][2*N+F+c]=1;
           }
          }
          for(int i=2*N+1;i<=2*N+F;++i)
            map[0][i]=1;
            for(int i=2*N+F+1;i<=2*N+F+D;++i)
              map[i][2*N+F+D+1]=1;
              E_k(0,2*N+F+D+1);
     }return 0;
}
    


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值