zoukankan      html  css  js  c++  java
  • POJ1149 PIGS 【最大流 + 构图】

    题目链接:http://poj.org/problem?id=1149

    PIGS
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions:24094   Accepted: 10982

    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.
    题目大意:
    1.给定m个猪棚,n个顾客,接下来n行每行代表第i个顾客有k个猪棚的钥匙,以及该顾客的需求量。
    2.注意题目的要求,主人可以在顾客打开了猪棚的时候对猪棚中的猪数量进行调动,所以,为了尽可能满足所有顾客的需求,建图需要体现对猪的调动。
    3.对于每一个猪棚,第一个打开它的顾客,我们将源点向该顾客建边,容量为猪棚的猪数量。对于以后再次光顾该猪棚的顾客,我们将第一次光顾该猪棚的顾客与以后光顾该猪棚的顾客建边,容量为inf。最后将每个顾客与终点连边,边的容量为顾客的需求量。至于为什么这样建图,可以理解为将猪全部给了第一个光顾该猪棚的顾客,以后再需要的顾客可以从他这里拿,这样的话可以确保尽可能多的满足后来的顾客。
    代码如下:
      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<algorithm>
      4 #include<queue>
      5 #define mem(a, b) memset(a, b, sizeof(a))
      6 using namespace std;
      7 const int MAXM = 1100; //猪圈数目上界 
      8 const int MAXN = 110; //顾客数目上界 
      9 const int inf = 0x3f3f3f3f;
     10 
     11 int m, n; //猪棚数目 顾客数目 
     12 int num[MAXM], first[MAXM], vis[MAXM];//每个猪圈里猪的数目 每个猪圈第一个顾客 每个猪圈是否已经有第一个顾客买了 
     13 int head[MAXN], cnt;
     14 int dep[MAXN];
     15 queue<int> Q;
     16 
     17 struct Edge
     18 {
     19     int to, next, flow;
     20 }edge[4 * MAXN + 2 * MAXN * MAXN];
     21 
     22 void add(int a, int b, int c)
     23 {
     24     cnt ++;
     25     edge[cnt].to = b;
     26     edge[cnt].flow = c;
     27     edge[cnt].next = head[a];
     28     head[a] = cnt;
     29 }
     30 
     31 int bfs(int st, int ed)
     32 {
     33     if(st == ed)
     34         return 0;
     35     while(!Q.empty())    Q.pop();
     36     mem(dep, -1);
     37     dep[st] = 1;
     38     Q.push(st);
     39     while(!Q.empty())
     40     {
     41         int index = Q.front();
     42         Q.pop();
     43         for(int i = head[index]; i != -1; i = edge[i].next)
     44         {
     45             int to = edge[i].to;
     46             if(edge[i].flow > 0 && dep[to] == -1)
     47             {
     48                 dep[to] = dep[index] + 1;
     49                 Q.push(to);
     50             }
     51         }
     52     }
     53     return dep[ed] != -1;
     54 }
     55 
     56 int dfs(int now, int ed, int zx)
     57 {
     58     if(now == ed)
     59         return zx;
     60     for(int i = head[now]; i != -1; i = edge[i].next)
     61     {
     62         int to = edge[i].to;
     63         if(dep[to] == dep[now] + 1 && edge[i].flow > 0)
     64         {
     65             int flow = dfs(to, ed, min(zx, edge[i].flow));
     66             if(flow > 0)
     67             {
     68                 edge[i].flow -= flow;
     69                 edge[i ^ 1].flow += flow;
     70                 return flow;
     71             }
     72         }
     73     }
     74     return -1;
     75 }
     76 
     77 void dinic(int st, int ed)
     78 {
     79     int ans = 0;
     80     while(bfs(st, ed))
     81     {
     82         while(1)
     83         {
     84             int inc = dfs(st, ed, inf);
     85             if(inc == -1)
     86                 break;
     87             ans += inc;
     88         }
     89     }
     90     printf("%d
    ", ans);
     91 }
     92 
     93 int main()
     94 {
     95     int m, n;
     96     scanf("%d%d", &m, &n);
     97     int st = 0, ed = n + 1;
     98     mem(head, -1), cnt = -1;
     99     mem(first, -1), mem(vis, 0);
    100     for(int i = 1; i <= m; i ++)
    101         scanf("%d", &num[i]);
    102     for(int i = 1; i <= n; i ++)
    103     {
    104         int k;
    105         scanf("%d", &k);
    106         for(int j = 1; j <= k; j ++)
    107         {
    108             int x;
    109             scanf("%d", &x);//猪圈编号 
    110             if(!vis[x])
    111             {
    112                 first[x] = i;
    113                 vis[x] = 1;
    114                 add(st, i, num[x]);
    115                 add(i, st, 0);
    116             }
    117             else
    118             {
    119                 add(first[x], i, inf);
    120                 add(i, first[x], 0);
    121             }
    122         }
    123         int x;
    124         scanf("%d", &x);
    125         add(i, ed, x);
    126         add(ed, i, 0);
    127     }
    128     dinic(st, ed);
    129     return 0;
    130 }
    POJ1149
  • 相关阅读:
    MySQL语法
    Linux常用命令大全
    触发器使用UTL_SMTP包发送邮件
    MySQL——触发器的创建和使用总结
    MySQL数据库备份
    Nginx配置文件(nginx.conf)配置详解
    JS弹出框,打开文件,保存文件,另存为。。。。
    java excel两种操作方式
    Zookeeper的优缺点
    activemq linux安装
  • 原文地址:https://www.cnblogs.com/yuanweidao/p/11481174.html
Copyright © 2011-2022 走看看