• POJ1149 PIGS [最大流 建图]


    PIGS
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 20662   Accepted: 9435

    Description

    Mirko works on a pig farm that consists of M locked pig-houses and Mirko can't unlock any pighouse because he doesn't have the keys. Customers come to the farm one after another. Each of them has keys to some pig-houses and wants to buy a certain number of pigs. 
    All data concerning customers planning to visit the farm on that particular day are available to Mirko early in the morning so that he can make a sales-plan in order to maximize the number of pigs sold. 
    More precisely, the procedure is as following: the customer arrives, opens all pig-houses to which he has the key, Mirko sells a certain number of pigs from all the unlocked pig-houses to him, and, if Mirko wants, he can redistribute the remaining pigs across the unlocked pig-houses. 
    An unlimited number of pigs can be placed in every pig-house. 
    Write a program that will find the maximum number of pigs that he can sell on that day.

    Input

    The first line of input contains two integers M and N, 1 <= M <= 1000, 1 <= N <= 100, number of pighouses and number of customers. Pig houses are numbered from 1 to M and customers are numbered from 1 to N. 
    The next line contains M integeres, for each pig-house initial number of pigs. The number of pigs in each pig-house is greater or equal to 0 and less or equal to 1000. 
    The next N lines contains records about the customers in the following form ( record about the i-th customer is written in the (i+2)-th line): 
    A K1 K2 ... KA B It means that this customer has key to the pig-houses marked with the numbers K1, K2, ..., KA (sorted nondecreasingly ) and that he wants to buy B pigs. Numbers A and B can be equal to 0.

    Output

    The first and only line of the output should contain the number of sold pigs.

    Sample Input

    3 3
    3 1 10
    2 1 2 2
    2 1 3 3
    1 2 6

    Sample Output

    7

    Source


    中文题面

    1280: Emmy卖猪pigs

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 183  Solved: 123
    [Submit][Status][Discuss]

    Description

    Emmy在一个养猪场工作。这个养猪场有M个锁着的猪圈,但Emmy并没有钥匙。顾客会到养猪场来买猪,一个接着一个。每一位顾客都会有一些猪圈的钥匙,他们会将这些猪圈打开并买走固定数目的猪。 所有顾客有的钥匙和他们需要买猪的数量在事先都告诉了Emmy,于是Emmy要订一个计划,使得卖出去的猪最多。 买卖的过程是这样的:一个顾客前来,并打开所有他可以打开的猪圈。然后Emmy从这些猪圈里牵出固定数目的猪卖给顾客(最多只能和顾客需要数相等),并可以重新安排这些开着的猪圈中的猪。 每个猪圈可以存放任意数目的猪。 写一个程序,使得Emmy能够卖出去尽可能多的猪。

    Input

    第一行有两个整数:M和N,表示猪圈数和顾客数。 第二行有M个整数,表示每个猪圈初始时有多少猪。 接下来的N行按照前来的次序描述了每一个顾客,每行的格式如下: A K1 K2…KA B A表示该顾客拥有的钥匙数,K1...KA表示每个钥匙所对应的猪圈,B表示该顾客需要购买的猪的数目。

    Output

    仅包含一个整数,即最多能卖出去的猪的数目。

    朴素见图的话,因为一个人的购买影响下一个人,所以可以按每个购买分层
    猪圈和人作为点,s连猪圈一开始数量,人连t购买数
    每个人(购买)作为一个层次,从上个层次到下个层次同一个猪圈连INF,然后可以购买的(能合并在一起)互相连起来、
    这样点n+nm,边2nm
     
    考虑一些边没用,没必要每个人的购买都重新弄一批猪圈的点,保存每个猪圈当前到了那个人手里然后连INF就行了,因为下一个人能买这个猪圈,以前拿着猪圈的人打开的所有猪圈都可以
    这样点n,边nm
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int N=105,M=1005,INF=1e9;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    
    int m,n,s,t;
    int pig[M],now[M];
    struct edge{
        int v,c,f,ne;
    }e[N*M<<1];
    int cnt,h[N];
    inline void ins(int u,int v,int c){
        cnt++;
        e[cnt].v=v;e[cnt].c=c;e[cnt].f=0;e[cnt].ne=h[u];h[u]=cnt;
        cnt++;
        e[cnt].v=u;e[cnt].c=0;e[cnt].f=0;e[cnt].ne=h[v];h[v]=cnt;
    }
    int q[N],head,tail,vis[N],d[N];
    bool bfs(){
        memset(vis,0,sizeof(vis));
        memset(d,0,sizeof(d));
        head=tail=1;
        d[s]=0;vis[s]=1;
        q[tail++]=s;
        while(head!=tail){
            int u=q[head++];
            for(int i=h[u];i;i=e[i].ne){
                int v=e[i].v;
                if(!vis[v]&&e[i].c>e[i].f){
                    vis[v]=1;
                    d[v]=d[u]+1;
                    q[tail++]=v;
                    if(v==t) return true;
                }
            }
        }
        return false;
    }
    int cur[N];
    int dfs(int u,int a){
        if(u==t||a==0) return a;
        int flow=0,f;
        for(int &i=cur[u];i;i=e[i].ne){
            int v=e[i].v;
            if(d[v]==d[u]+1&&(f=dfs(v,min(a,e[i].c-e[i].f)))>0){
                flow+=f;
                e[i].f+=f;
                e[((i-1)^1)+1].f-=f;
                a-=f;
                if(a==0) break;
            }
        }
        return flow;
    }
    int dinic(){
        int flow=0;
        while(bfs()){
            for(int i=s;i<=t;i++) cur[i]=h[i];
            flow+=dfs(s,INF);
        }
        return flow;
    }
    int main(){
        //freopen("in.txt","r",stdin);
        m=read();n=read();s=0;t=n+1;
        for(int i=1;i<=m;i++) pig[i]=read();
        for(int i=1;i<=n;i++){
            int A=read(),B,x;
            while(A--){
                x=read();
                if(!now[x]) ins(s,i,pig[x]),now[x]=i;
                else ins(now[x],i,INF),now[x]=i;
            }
            B=read();
            ins(i,t,B);
        }
        printf("%d",dinic());
    }
     
     

  • 相关阅读:
    Zookeeper:Windows下Zookeeper启动zkServer.cmd闪退问题
    单元测试:单元测试多模块项目不同模块组件不能@autowired问题
    SpringBoot:springBoot注解大全
    单元测试:Junit基本注解@BeforeClass、@AfterClass、@Before、@After、@Test、
    知识点:日志打印@Slf4j 注解的使用方法
    单元测试:@FixMethodOrder注解指定测试方法的执行顺序
    资源:zookeeper下载地址
    资源:HTML调色板
    其他:《后端架构师技术图谱》
    Linux:从windows到linux的shell脚本编码和格式
  • 原文地址:https://www.cnblogs.com/candy99/p/6257524.html
Copyright © 2020-2023  润新知