POJ1149 PIGS [最大流 建图]

Posted Candy?

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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());
}

 

 
 

以上是关于POJ1149 PIGS [最大流 建图]的主要内容,如果未能解决你的问题,请参考以下文章

poj 1149 PIGS最大流

Poj1149Pigs(最大流)

poj1149PIGS——网络最大流

网络流(最大流):POJ 1149 PIGS

POJ 1149 - PIGS - [最大流构图]

POJ 1149 PIGS (最大流)