最大流:HDU-4292(Food)

#include <iostream>
#include <cstdio>
#include <cstring>
#define INF 0x7fffffff 
#define MAXN 1000 
#define MAXE 200000 
using namespace std; 
int N,F,D,Max; 
struct Edge {
    int to,next,c;
}e[MAXE];
int size,head[MAXN]; 
void addedge(int from,int to,int c
{
   e[size].to=to;
    e[size].c = c;
    e[size].next=head[from];
    head[from]=size++; 
    e[size].to=from;
    e[size].c=0;
    e[size].next=head[to];
    head[to]=size++; 
} 
int dis[MAXN],gap[MAXN],cur[MAXN],pre[MAXN]; 
int SAP_GAP() 
{
     int start=0,end=Max+1,NN=Max+2; 
       int cur_flow,flow_ans=0,i,u,tmp,neck; 
       memset(dis,0,sizeof(dis)); 
        memset(gap,0,sizeof(gap)); 
        memset(pre,-1,sizeof(pre));
      for(i=0;i<=Max+1;i++)
        cur[i]=head[i]; 
       u=start;
    gap[0]=NN; 
      while(dis[start]<NN
      {
   if(u==end
           {
   cur_flow=INF; 
                   for(i=start;i!=end;i=e[cur[i]].to
                      {
   if(cur_flow>e[cur[i]].c
                             {
                    neck=i;
                    cur_flow=e[cur[i]].c;
                } 
                      } 
                    for(i=start;i!=end;i=e[cur[i]].to
                      { 
                                 tmp=cur[i]; 
                                 e[tmp].c-=cur_flow; 
                                      e[tmp^1].c+=cur_flow;
                   } 
                           u=neck;
            flow_ans+=cur_flow
            } 
           for(i=cur[u];i!=-1;i=e[i].next) 
                         if(e[i].c&&dis[u]==dis[e[i].to]+1)
                break; 
           if(i!=-1)
        {
            cur[u]=i;
            pre[e[i].to]=u;
            u=e[i].to;
        } 
           else
        { 
                    if(--gap[dis[u]]==0)    break; 
                       cur[u]=head[u]; 
                    for(tmp=NN,i=head[u];i!=-1;i=e[i].next) 
                                 if(e[i].c)  tmp=min(tmp,dis[e[i].to]); 
                            dis[u]=tmp+1; 
                           gap[dis[u]]++; 
                    if(u!=start)    u=pre[u]; 
                
    } 
  return flow_ans
} 
void init() 
{
   char str[MAXN];
    int k;
    size=0; 
    memset(head,-1,sizeof(head)); 
     Max=N*2+F+D; 
     for(int i=1;i<=F;i++)
    {
        scanf("%d",&k);
        addedge(0,i,k);
    } 
     for(int i=1;i<=D;i++)
    {
        scanf("%d",&k);
        addedge(N*2+F+i,Max+1,k);
    } 
     for(int i=1;i<=N;i++)
        addedge(F+i,F+N+i,1); 
     for(int i=1;i<=N;i++) 
        {
     scanf("%s",str); 
              for(int j=1;j<=F;j++)
            if(str[j-1]=='Y')
                addedge(j,F+i,1);
    } 
             for(int i=1;i<=N;i++) 
                {   scanf("%s",str); 
                  for(int j=1;j<=D;j++) 
                              if(str[j-1]=='Y')
                addedge(F+N+i,F+N*2+j,1);
            
      } 
int main() 
{
    //freopen("in.txt","r",stdin); 
 while(scanf("%d%d%d",&N,&F,&D)!=EOF
         {
        init();
        printf("%d\n",SAP_GAP());
    } 
     return 0
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值