PIGS POJ

来源:互联网 发布:水滴源码 编辑:程序博客网 时间:2024/06/05 16:31

点击打开链接

这个题的建图比较有难度也比较神奇 以每个买主为中心抽象为一层 而这每一层又包含了其他所有猪圈与该买主的关系

具体请点击这篇博客 有图看 很直观

点击打开链接

#include <stdio.h>#include <queue>#include <cstring>#include <algorithm>using namespace std;#define N 1e9struct node{    int v;    int w;    int next;};node edge[10010];int e[110][1010];int pig[1010],need[110];int first[110],dis[110],gap[110],cur[110],pre[110];int n,m,num,ss,ee,ans;void addedge(int u,int v,int w);void init();void build();void isap();void bfs();int main(){    int tar[1010];    int t,i,j,amt;    while(scanf("%d%d",&m,&n)!=EOF)    {        init();        build();        isap();        printf("%d\n",ans);    }    return 0;}void addedge(int u,int v,int w){    edge[num].v=v;    edge[num].w=w;    edge[num].next=first[u];    first[u]=num++;    return;}void init(){    int i,j,t1,t2;    memset(e,0,sizeof(e));    for(i=1;i<=m;i++)    {        scanf("%d",&pig[i]);    }    for(i=1;i<=n;i++)    {        scanf("%d",&t1);        for(j=1;j<=t1;j++)        {            scanf("%d",&t2);            e[i][t2]=1;        }        scanf("%d",&need[i]);    }    return;}void build(){    int tem[110],book[1010];    int i,j,t;    memset(tem,0,sizeof(tem));    memset(book,0,sizeof(book));    memset(first,-1,sizeof(first));    ss=n+1,ee=n+2,num=0;    for(i=1;i<=n;i++)    {        for(j=1;j<=m;j++)        {            if(e[i][j]==1&&book[j]==0)            {                tem[i]+=pig[j];                book[j]=1;            }        }    }    for(i=1;i<=n;i++)    {        if(tem[i]>0)        {            addedge(ss,i,tem[i]);            addedge(i,ss,0);        }        addedge(i,ee,need[i]);        addedge(ee,i,0);    }    for(j=1;j<=m;j++)    {        t=-1;        for(i=1;i<=n;i++)        {            if(e[i][j]==1)            {                if(t!=-1)                {                    addedge(t,i,N);                    addedge(i,t,0);                }                t=i;            }        }    }    num=n+2;    return;}void isap(){    int j,u,v,w,flow,minn;    bfs();    memcpy(cur,first,sizeof(first));    memset(pre,-1,sizeof(pre));    ans=0,u=ss,flow=N;    while(dis[ss]<num)    {        int &i=cur[u];        for(;i!=-1;i=edge[i].next)        {            v=edge[i].v,w=edge[i].w;            if(w>0&&dis[v]+1==dis[u])            {                pre[v]=i;                u=v,flow=min(flow,w);                if(u==ee)                {                    while(u!=ss)                    {                        edge[pre[u]].w-=flow;                        edge[pre[u]^1].w+=flow;                        u=edge[pre[u]^1].v;                    }                    ans+=flow,flow=N;                }                break;            }        }        if(i==-1)        {            if(--gap[dis[u]]==0) break;            cur[u]=first[u];            minn=num-1;            for(j=first[u];j!=-1;j=edge[j].next)            {                v=edge[j].v,w=edge[j].w;                if(w>0)                {                    minn=min(minn,dis[v]);                }            }            dis[u]=minn+1;            gap[dis[u]]++;            if(u!=ss)            {                u=edge[pre[u]^1].v;            }        }    }    return;}void bfs(){    queue <int> que;    int i,u,v;    memset(dis,-1,sizeof(dis));    memset(gap,0,sizeof(gap));    que.push(ee);    dis[ee]=0;    while(!que.empty())    {        u=que.front();        que.pop();        gap[dis[u]]++;        for(i=first[u];i!=-1;i=edge[i].next)        {            v=edge[i].v;            if(dis[v]==-1)            {                que.push(v);                dis[v]=dis[u]+1;            }        }    }    return;}