• POJ 1149 PIGS


    Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %I64d & %I64u

    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

    建图思路很好

    此处搬运自AaronPolaris的博客:

      构图方式:

      ①把每个顾客看作除源点和汇点以外的节点。

      ②从源点向每个猪圈的第一个顾客连一条边,容量为该猪圈最初的猪的数量。

      ③每个猪圈的前后两个顾客之间连一条边,容量为正无穷。因为可以任意分配每个猪圈中的猪的数量。

      ④从每个顾客向汇点连一条边,容量为要购买的猪的数量。

    搬运完毕

     1 //POJ - 1149 PIGS
     2 /*by SilverN*/
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdio>
     7 #include<cmath>
     8 #include<queue>
     9 using namespace std;
    10 const int INF=0xfffff;
    11 const int mxn=420;//最大顾客数 
    12 const int mxm=1200;//最大猪圈数
    13 int s,t;
    14 int w[mxn][mxn];//容量
    15 int d[mxn];//深度 
    16 int house[mxm];//猪圈里猪数量 
    17 int last[mxn];
    18 int M,N;//猪圈数,顾客数 
    19 
    20 void init(){
    21     int i,j;
    22 
    23     scanf("%d%d",&M,&N);
    24     int num;
    25     int x;
    26     s=0;t=N+1;
    27     for(i=1;i<=M;i++)scanf("%d",&house[i]);
    28     for(i=1;i<=N;i++){
    29         scanf("%d",&num);
    30         for(j=1;j<=num;j++){
    31             scanf("%d",&x);
    32             if(!last[x])w[s][i]+=house[x];
    33             //如果是来到此猪圈的第一个顾客,从源点连边到顾客点,容量为猪圈里猪的数量 
    34             else w[last[x]][i]=INF;
    35             //在同一个猪圈的前后顾客之间连边 
    36             last[x]=i;
    37         }
    38         scanf("%d",&x);
    39         w[i][t]=x;//顾客到汇点连边,容量为欲购买量 
    40     }
    41     return;
    42 }
    43 bool BFS(int s){
    44     queue<int>q;
    45     memset(d,-1,sizeof(d));
    46     q.push(s);
    47     d[s]=0;
    48     int i;
    49     while(!q.empty()){
    50         int u=q.front();
    51         if(u==t)return true;
    52         q.pop();
    53         for(i=0;i<=t;i++){
    54             if(w[u][i] && d[i]==-1){
    55                 d[i]=d[u]+1;
    56                 q.push(i);
    57             }
    58         }
    59     }
    60     return false;
    61 }
    62 int DFS(int x,int low){
    63     if(x==t)return low;
    64     int i,a;
    65     for(i=0;i<=t;i++){
    66         if(w[x][i]>0 && d[i]==d[x]+1)
    67           if(a=DFS(i,min(w[x][i],low))){
    68               w[x][i]-=a;
    69               w[i][x]+=a;
    70               return a;
    71           }
    72     }
    73     return 0;
    74 }
    75 void dinic(){
    76     int ans=0;
    77     int flow=0;
    78     while(BFS(s)){
    79         while(flow=DFS(s,INF)){
    80             ans+=flow;
    81         }
    82     }
    83     printf("%d
    ",ans);
    84     return;
    85 }
    86 int main(){
    87     init();
    88     dinic();
    89     return 0;
    90 }
  • 相关阅读:
    NYOJ 38布线问题
    NYOJ 106背包问题
    基于贪心算法的几类区间覆盖问题 nyoj 12喷水装置(二) nyoj 14会场安排问题
    HDOJ 2546饭卡(01背包问题)
    FBI树-数据结构(二叉树)
    二叉树遍历(flist)(二叉树,已知中序层序,求先序)
    求先序排列(二叉树已知中序和后序,求先序)
    滑雪(dp)
    Python——plot可视化数据,作业8(python programming)
    数据库SQL语言学习----左外连接,右外连接,外连接,自然连接的形象对比
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5589523.html
Copyright © 2020-2023  润新知