zoukankan      html  css  js  c++  java
  • POJ 1149--PIGS

    题意:

      有m个猪圈,n个顾客,这些顾客按顺序购买,每个顾客有若干猪圈的钥匙,可以从其中购买猪,在一个顾客买完之后,可以将这个顾客可以打开的猪圈内的猪重新调整,问最多这些顾客能买走多少猪

    算法:网路最大流

        用顾客来作为节点,顾客数最多为100,时间和空间都可以达到要求。新增源点s,汇点t,对于每个顾客来说,如果他是第一个打开某猪圈的,则从s向他连一条容量为该猪圈初始值的边,如果与源点的流量已经不是0,则合并,如果不是第一个,则从上一个打开该猪圈的顾客向这个顾客连一条容量为+oo的边,每个顾客向汇点连一条容量为该顾客希望购买的猪的数量的边

        首先按上面的方法构造一个容量网路,再从初始流(零流)出发进行标号,调整。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define INF 300000000
    #define MAXM 1000
    #define MAXN 100
    int s,t;        //源点,汇点
    int customer[MAXN+2][MAXN+2];//各节点之间的容量
    int flow[MAXN+2][MAXN+2];    //节点之间的流量
    int i,j;
    void init()
    {
        int M,N;
        int num;
        int k;                 //第k个猪圈的钥匙
        int house[MAXM] ;   //储存每个猪圈中猪的个数
        int last[MAXM];  //储存每个猪圈的前一个顾客的钥匙数
        memset(last,0,sizeof(last));
        memset(customer,0,sizeof(customer));
        scanf("%d%d",&M,&N);
        s=0;
        t=N+1;
        for(i=1; i<=M; i++)
            scanf("%d",&house[i]);
        for(i=1; i<=N; i++)
        {
            scanf("%d",&num);
            for(j=0; j<num; j++)
            {
                scanf("%d",&k);
                if(last[k]==0)
                    customer[s][i]=customer[s][i]+house[k];
                else
                    customer[last[k]][i]=INF;
                last[k]=i;
            }
            scanf("%d",&customer[i][t]);
        }
    }
    void ford()
    {
        int prev[MAXN+2];
        int minflow[MAXN+2];
        int queue[MAXN+2];
        int qs,qe;
        int v;
        int p;
        for(i=0; i<MAXN+2; i++)
        {
            for(j=0; j<MAXN+2; j++)
            {
                flow[i][j]=0;
            }
        }
        minflow[0]=INF;
        while(1)
        {
            for(i=0; i<MAXN+2; i++)
                prev[i]=-2;
            prev[0]=-1;
            qs=0;
            queue[qs]=0;
            qe=1;
            while(qe>qs&&prev[t]==-2)
            {
                v=queue[qs];
                qs++;
                for(i=0; i<t+1; i++)
                {
                    if(prev[i]==-2&&(p=customer[v][i]-flow[v][i]))
                    {
                        prev[i]=v;
                        queue[qe]=i;
                        qe++;
                        minflow[i]=(minflow[v]<p)?minflow[v]:p;
                    }
                }
            }
            if(prev[t]==-2) break;
            for(i=prev[t],j=t;i!=-1;j=i,i=prev[i])
            {
                flow[i][j]=flow[i][j]+minflow[t];
                flow[j][i]=-flow[i][j];
            }
        }
        p=0;
        for(i=0;i<t;i++)
        {
            p=p+flow[i][t];
        }
        printf("%d
    ",p);
    }
    int main()
    {
        init();
        ford();
        return 0;
    }
  • 相关阅读:
    bzoj2018 [Usaco2009 Nov]农场技艺大赛
    2014.9.27模拟赛【栅栏迷宫】
    cf471B MUH and Important Things
    cf471A MUH and Sticks
    bzoj3016 [Usaco2012 Nov]Clumsy Cows
    bzoj3404 [Usaco2009 Open]Cow Digit Game又见数字游戏
    bzoj1633 [Usaco2007 Feb]The Cow Lexicon 牛的词典
    bzoj3299 [USACO2011 Open]Corn Maze玉米迷宫
    codevs1040 统计单词个数
    codevs1039 数的划分
  • 原文地址:https://www.cnblogs.com/fenhong/p/7265434.html
Copyright © 2011-2022 走看看