poj 1149 pigs ---- 最大流

  题意以及分析:http://ycool.com/post/zhhrrm6#rule3

  主要是建图,简化图,然后在套最大流的模板。

#include <iostream>
#include<string.h>
#include<cstdio>
using namespace std;


struct Node
{
    int v,cap,flow,next;

    Node(){}
    Node(int _v,int _cap,int _flow,int _next)
    {
        v=_v;
        cap=_cap;
        flow=_flow;
        next=_next;
    }
};


const int INF=1000000000;
Node edges[120005];
int pig[1005],a[1005][105];
int n,m,s,t,head[1005],e;


void Add(int u,int v,int cap)
{
    edges[e]=Node(v,cap,0,head[u]);
    head[u]=e++;
    edges[e]=Node(u,0,0,head[v]);
    head[v]=e++;
}

int num[1005],h[1005],curedge[1005],pre[1005];

int Maxflow(int s,int t,int n)
{
    int ans=0,i,k,x,d,u;

    memset(num,0,sizeof(num));
    memset(h,0,sizeof(h));
    for(i=0;i<=n;i++) curedge[i]=head[i];
    num[n]=n;u=s;
    while(h[u]<n)
    {
        if(u==t)
        {
            d=INF+1;
            for(i=s;i!=t;i=edges[curedge[i]].v) if(d>edges[curedge[i]].cap)
                k=i,d=edges[curedge[i]].cap;
            for(i=s;i!=t;i=edges[curedge[i]].v)
            {
                x=curedge[i];
                edges[x].cap-=d;
                edges[x].flow+=d;
                edges[x^1].cap+=d;
                edges[x^1].flow-=d;
            }
            ans+=d;u=k;
        }
        for(i=curedge[u];i!=-1;i=edges[i].next) if(edges[i].cap>0&&h[u]==h[edges[i].v]+1)
            break;
        if(i!=-1)
        {
            curedge[u]=i;
            pre[edges[i].v]=u;
            u=edges[i].v;
        }
        else
        {
            if(--num[h[u]]==0) break;
            curedge[u]=head[u];
            for(x=n,i=head[u];i!=-1;i=edges[i].next) if(edges[i].cap>0&&h[edges[i].v]<x)
                x=h[edges[i].v];
            h[u]=x+1;num[h[u]]++;
            if(u!=s) u=pre[u];
        }
    }
    return ans;
}

int main()
{
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        int i,j,x,p,num;

        s=0;t=n+1;
        memset(head,-1,sizeof(head));
        e=0;
        for(i=1;i<=m;i++) scanf("%d",&pig[i]);
        for(i=1;i<=m;i++) a[i][0]=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&x);
            while(x--) scanf("%d",&p),a[p][++a[p][0]]=i;
            scanf("%d",&num);
            Add(i,t,num);
        }
        for(i=1;i<=m;i++) if(a[i][0]) Add(s,a[i][1],pig[i]);
        for(i=1;i<=m;i++) for(j=1;j<a[i][0];j++) Add(a[i][j],a[i][j+1],INF);
        printf("%d
",Maxflow(s,t,t));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/yongren1zu/p/3260839.html