POJ 1149 PIGS (最大流)

本文介绍了一个经典的农场买卖模拟问题,通过构建特殊的网络流模型解决最大化的猪只销售问题。利用ISAP算法进行求解,详细展示了如何通过设置不同的节点与边来模拟顾客开锁买猪的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PIGS
Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 13538Accepted: 5973

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
 
经典构图题。首先源点和每个人连边,权值为人的购买量;其次人与猪圈连边,容量为无穷大;然后猪圈与汇点连边,容量为猪圈内猪的数量;最后对于当前人,如果他能开的猪圈之前有人开过,那么将这人与之前能开这个猪圈的人连边,权值为无穷大。最后直接跑ISAP。

 

//340 KB	0 ms	
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define SIZE 1111
#define inf 0x7fffffff

using namespace std;

struct node
{
    int to,val,next;
}edge[SIZE*111];

int M,N,sc,sk,pt;
int head[SIZE],idx;
bool cnt[111][SIZE];
int dis[SIZE],gap[SIZE];

void addnode(int from,int to,int val)
{
    edge[idx].to = to;
    edge[idx].val = val;
    edge[idx].next = head[from];
    head[from] =  idx ++;
    edge[idx].to = from;
    edge[idx].val = 0;
    edge[idx].next = head[to];
    head[to] = idx ++;
}

int dfs(int cur,int cval)
{
    if(cur == sk)
        return cval;
    int mindis = pt - 1, tval = cval;
    for(int i=head[cur]; i!=-1; i=edge[i].next)
    {
        int to = edge[i].to;
        if(edge[i].val > 0)
        {
            if(dis[to] + 1 == dis[cur])
            {
                int val = dfs(to,min(edge[i].val,tval));
                tval -= val;
                edge[i].val -= val;
                edge[i^1].val += val;
                if(dis[sc] >= pt)
                    return cval-tval;
                if(tval == 0)
                    break;
            }
            if(dis[to] < mindis)
                mindis = dis[to];
        }
    }
    if(cval == tval)
    {
        --gap[dis[cur]];
        if(!gap[dis[cur]])
            dis[sc] = pt;
        dis[cur] = mindis + 1;
        ++gap[dis[cur]];
    }
    return cval-tval;
}

void sap()
{
    memset(dis,0,sizeof(dis));
    memset(gap,0,sizeof(gap));
    int ret = 0;
    gap[sc] = pt;
    while(dis[sc] < pt)
        ret += dfs(sc,inf);
    printf("%d\n",ret);
}

void read()
{
    idx = 0;
    sc = 0, sk = N+M+1, pt = sk+1;
    memset(head,-1,sizeof(head));
    memset(cnt,0,sizeof(cnt));
    int A,B,t;
    for(int i=1; i<=M; i++)
    {
        scanf("%d",&t);
        addnode(N+i,sk,t);
    }
    for(int i=1; i<=N; i++)
    {
        scanf("%d",&A);
        for(int j=1; j<=A; j++)
        {
            scanf("%d",&t);
            cnt[i][t] = true;
            for(int k=i-1; k>=1; k--)
            {
                if(cnt[k][t])
                    addnode(i,k,inf);
            }
            addnode(i,N+t,inf);
        }
        scanf("%d",&B);
        addnode(sc,i,B);
    }
}

int main()
{
    while(~scanf("%d%d",&M,&N))
    {
        read();
        sap();
    }
    return 0;
}


 


                
内容概要:本文详细介绍了施耐德M580系列PLC的存储结构、系统硬件架构、上电写入程序及CPU冗余特性。在存储结构方面,涵盖拓扑寻址、Device DDT远程寻址以及寄存器寻址三种方式,详细解释了不同类型的寻址方法及其应用场景。系统硬件架构部分,阐述了最小系统的构建要素,包括CPU、机架和模块的选择与配置,并介绍了常见的系统拓扑结构,如简单的机架间拓扑和远程子站以太网菊花链等。上电写入程序环节,说明了通过USB和以太网两种接口进行程序下载的具体步骤,特别是针对初次下载时IP地址的设置方法。最后,CPU冗余部分重点描述了热备功能的实现机制,包括IP通讯地址配置和热备拓扑结构。 适合人群:从事工业自动化领域工作的技术人员,特别是对PLC编程及系统集成有一定了解的工程师。 使用场景及目标:①帮助工程师理解施耐德M580系列PLC的寻址机制,以便更好地进行模块配置和编程;②指导工程师完成最小系统的搭建,优化系统拓扑结构的设计;③提供详细的上电写入程序指南,确保程序下载顺利进行;④解释CPU冗余的实现方式,提高系统的稳定性和可靠性。 其他说明:文中还涉及一些特殊模块的功能介绍,如定时器事件和Modbus串口通讯模块,这些内容有助于用户深入了解M580系列PLC的高级应用。此外,附录部分提供了远程子站和热备冗余系统的实物图片,便于用户直观理解相关概念。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值