(最大流)HDU4292 Food

来源:互联网 发布:android编程经典200例 编辑:程序博客网 时间:2024/06/05 18:12

这道题是POJ3281的加强,食物F和饮料D现在有了供应量,增广路的次数增多,邻接矩阵就不能用了,只能用邻接表。

还是采取POJ3281的拆点方法,将人拆成两个点。

这次试着使用Dinic算法来求解最大流问题,有机会的话会将Dinic算法改写为非递归写法。


//Stronger situation of POJ3281, needs adjcent link table.#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct EDGE{    int v,cap,next;}e[200005];int d[805],head[805];int n,en,N,D,F;const int inf=(1<<31)-1;int src=0,des;bool bfs(int src){    int q[900];    q[0]=src;    memset(d,-1,sizeof(d));    d[src]=0;    int front=0,rear=1;    while(front<rear){        int index=q[front++];        for (int i=head[index];i!=-1;i=e[i].next){            if (d[e[i].v]<0 && e[i].cap>0){                d[e[i].v]=d[index]+1;                q[rear++]=e[i].v;            }        }    }    return (d[des]>0);}int dinic(int src,int sum){    if (src==des)        return sum;    int flow;    for (int i=head[src];i!=-1;i=e[i].next){        if (d[e[i].v]==d[src]+1 && e[i].cap>0 && (flow=dinic(e[i].v,min(sum,e[i].cap)))){            e[i].cap-=flow;            e[i^1].cap+=flow;            return flow;        }    }    d[src]=-1;    return 0;}void addedge(int u,int v,int cap){    e[en].v=v;e[en].cap=cap;e[en].next=head[u];head[u]=en++;    e[en].v=u;e[en].cap=0;e[en].next=head[v];head[v]=en++;}int main(){    while(scanf("%d%d%d",&N,&F,&D)!=EOF){        n=N*2+F+D;        memset(head,-1,sizeof(head));        des=n+1;        en=0;        for (int i=1;i<=F;i++){            int amount;            scanf("%d",&amount);            addedge(src,i,amount);        }        for (int i=1+F+2*N;i<=D+F+2*N;i++){            int amount;            scanf("%d",&amount);            addedge(i,des,amount);        }        for (int i=1+F;i<=N+F;i++)            addedge(i,i+N,1);        for (int i=1;i<=N;i++){            char r[205];            scanf("%s",r);            for (int j=0;j<F;j++){                if (r[j]=='Y')                    addedge(j+1,i+F,1);            }        }        for (int i=1;i<=N;i++){            char r[205];            scanf("%s",r);            for (int j=0;j<D;j++){                if (r[j]=='Y')                    addedge(i+F+N,j+1+F+2*N,1);            }        }        int res=0;        int flow;        while(bfs(src)){            while(flow=(dinic(src,inf)))                res+=flow;        }        printf("%d\n",res);    }    return 0;}


0 0
原创粉丝点击