poj-1149-PIGS-网络流

来源:互联网 发布:植物大战僵尸2淘宝存档 编辑:程序博客网 时间:2024/04/27 15:00
题意:M个猪圈,N个顾客,每个顾客有一些的猪圈的钥匙,只能购买这些有钥匙的猪圈里的猪,而且要买一定数量的猪,每个猪圈有已知数量的猪,
但是猪圈可以重新打开,将猪的个数,重新分配,以达到卖出的猪的数量最多。
①构造网络,将顾客看成源点和汇点以外的结点,并设另外两个节点:源点和汇点。
②源点和每个猪圈的第一个顾客连边,边的权是开始时候猪圈中猪的数量。
③ 若源点和某个节点之间有重边,则将权合并
④顾客j紧跟顾客i之后打开某个猪圈,则<i.j>的权是正无穷。
⑤每个顾客和会点之间连边,边的权值是顾客所希望购买的猪的数量。
#include <stdio.h>#include <iostream>#include <algorithm>#include <string.h>#include<queue>using namespace std;#define INF 99999999const int maxn =1110;const int maxm =220000;const int oo = 1<<29;struct Arclist{    int cnt, head[maxn], dis[maxn];    int cur[maxn], pre[maxn], gap[maxn], aug[maxn];    struct node    {        int u, v, w, next;    }edge[maxm];    void init()    {        cnt = 0;        memset(head,-1,sizeof(head));    }    void add(int u, int v, int w)    {       // cout<<u<<" "<<v<<" "<<w<<endl;        edge[cnt].u = u;        edge[cnt].v = v;        edge[cnt].w = w;        edge[cnt].next = head[u];        head[u] = cnt++;        edge[cnt].u = v;        edge[cnt].v = u;        edge[cnt].w = 0;        edge[cnt].next = head[v];        head[v] = cnt++;    }    int sap(int s, int e, int n)    {        int max_flow = 0, u = s;        int mindis;        for(int i = 0; i <= n; i++)        {            cur[i] = head[i];            dis[i] = 0;            gap[i] = 0;        }        aug[s] = oo;        pre[s] = -1;        gap[0] = n;        while(dis[s]<n)        {            bool flag = false;            if(u==e)            {                max_flow += aug[e];                for(int v = pre[e]; v != -1; v = pre[v])                {                    int id = cur[v];                    edge[id].w -= aug[e];                    edge[id^1].w += aug[e];                    aug[v] -= aug[e];                    if(edge[id].w==0) u = v;                }            }            for(int id = cur[u]; id != -1; id = edge[id].next)            {                int v = edge[id].v;                if(edge[id].w>0 && dis[u]==dis[v]+1)                {                    flag = true;                    pre[v] = u;                    cur[u] = id;                    aug[v] = std::min(aug[u], edge[id].w);                    u = v;                    break;                }            }            if(flag==false)            {                if(--gap[dis[u]]==0) break;                mindis = n;                cur[u] = head[u];                for(int id = head[u]; id != -1; id = edge[id].next)                {                    int v = edge[id].v;                    if(edge[id].w>0 && dis[v]<mindis)                    {                        mindis = dis[v];                        cur[u] = id;                    }                }                dis[u] = mindis+1;                ++gap[dis[u]];                if(u!=s) u = pre[u];            }        }        return max_flow;    }}G;int w[maxn];int pre[maxn];int main(){    int n,m,i,j,a,b;    while(~scanf("%d%d",&n,&m))    {        G.init();        memset(pre,0,sizeof(pre));        for(i=1;i<=n;i++)        {            scanf("%d",&w[i]);        }        for(i=1;i<=m;i++)        {            scanf("%d",&a);            for(j=1;j<=a;j++)            {                scanf("%d",&b);                if(pre[b]==0)G.add(0,i,w[b]);                else G.add(pre[b],i,INF);                pre[b]=i;            }            scanf("%d",&a);            G.add(i,m+1,a);        }        cout<<G.sap(0,m+1,m+2)<<endl;    }    return 0;}


0 0
原创粉丝点击