poj1149--PIGS(最大流)

题意:

有m个猪圈 每个猪圈有不同数量的猪 [0, 1000]
有n个顾客 每个顾客需要Bi头猪 有Ai个钥匙 能打开Ai个不同的猪圈
顾客按顺序来买猪 只能买他有钥匙的猪 买完之后 这几个猪圈的猪可以相互转移

很神奇的题,建图简直太神奇~~

建图:

每个顾客和源点的流量为与该顾客的相连的猪圈且该猪圈之前没有与其他顾客相连的猪圈的猪数量和
每个顾客到汇点的流量是该顾客需要猪的数量
每个顾客需要与上一个选相同猪圈的顾客相连 因为猪圈之间可以相互换 不用考虑不同的猪圈

/*****************************************************
Problem: 1149		User: G_lory
Memory: 632K		Time: 16MS
Language: C++		Result: Accepted
*****************************************************/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;

const int N = 2010;
const int INF = 0x5f5f5f5f;

int flow[N];
int cap[N][N];
int pre[N];

queue<int> q;

int bfs(int src, int des)
{
    while (!q.empty()) q.pop();
    memset(pre, -1, sizeof pre);
    flow[src] = INF;
    pre[src] = -1;
    q.push(src);
    while (!q.empty())
    {
        int idx = q.front();
        q.pop();
        if (idx == des) break;
        for (int i = 0; i <= des; ++i)
        {
            if (pre[i] == -1 && cap[idx][i] > 0)
            {
                pre[i] = idx;
                flow[i] = min(cap[idx][i], flow[idx]);
                q.push(i);
            }
        }
    }
    if (pre[des] == -1) return -1;
    return flow[des];
}

int maxFlow(int src, int des)
{
    int ans = 0;
    int in = 0;
    while ((in = bfs(src, des)) != -1)
    {
        int k = des;
        while (k != src)
        {
            int last = pre[k];
            cap[last][k] -= in;
            cap[k][last] += in;
            k = last;
        }
        ans += in;
    }
    return ans;
}

int pig[N];
int last[N];

int main()
{
    int m, n;
    scanf("%d%d", &m, &n);
    for (int i = 1; i <= m; ++i)
        scanf("%d", &pig[i]);
    int num, a, b;
    for (int i = 1; i <= n; ++i)
    {
        scanf("%d", &num);
        for (int j = 1; j <= num; ++j)
        {
            scanf("%d", &a);
            if (!last[a])
            {
                last[a] = i;
                cap[0][i] += pig[a];
            }
            else
            {
                cap[ last[a] ][i] = INF;
                last[a] = i;
            }
        }
        scanf("%d", &b);
        cap[i][n + 1] = b;

    }
    printf("%d\n", maxFlow(0, n + 1));
    return 0;
}

  

时间: 2024-10-17 11:59:39

poj1149--PIGS(最大流)的相关文章

poj1149 PIGS --- 最大流EK

有m个猪圈,给出初始时每个猪圈里有几头猪,有n个顾客,每个顾客可能在某k个猪圈里买猪,总共要买a头. 顾客依次买猪,每次买完后,猪圈主人可以把猪圈里的猪转移到别的猪圈.每个猪圈的容量是无限大的. 问一天最多能卖多少猪. 整体读下来可以知道,要卖更多的猪,就要在每个顾客买之前,把尽量多的猪转移到下一个顾客要可以买的k个猪圈里. 也就是一个最大流问题. 把相邻两个顾客所选的猪圈之间建边,容量是inf. 添加一个源点与第一个顾客建边,权值为每个猪圈里猪的头数,第一次的容量是受猪圈里猪的数量限制的而不是

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 t

poj1149 PIGS 最大流(神奇的建图)

一开始不看题解,建图出错了.后来发现是题目理解错了.  if Mirko wants, he can redistribute the remaining pigs across the unlocked pig-houses. 题目中的这句话非常关键,没理解就错掉了.有很多人写的题解只告诉我们怎么做,却没告诉我们为什么要那样做. 这句话是的意思是可以重组打开过的猪圈.也就是当客人打开猪圈(他能打开的都打开了)以后,他选择了需要买的猪以后,Mirko可以随意把剩下的猪分配到打开的猪圈中.当然,我

POJ1149 PIGS 最大流-建模

题目链接: POJ1149 题意: 麦克是农场主有N个猪圈,每个猪圈都有一把锁但麦克没有钥匙.要买猪的顾客一个接一个来到养猪场,每个顾客有一些猪圈的钥匙,而且他们要买一定数量的猪.当每个顾客到来时,他将那些他拥有钥匙的猪圈全部打开:迈克从这些猪圈中挑出一些猪卖给他们:如果迈克愿意,迈克可以重新分配这些被打开的猪圈中的猪:当顾客离开时,猪圈再次被锁上.给出每个猪圈的初始的猪的数量,求麦克能卖出猪的最大数量 思路: 注意顾客是一个接一个有顺序来的 网络流以顾客为节点建模 1) 将顾客看作除源点和汇点

POJ1149 PIGS【特殊建图,最大流】

看题解做的,看懂了怎么建图后,套上挑战icpc的最大流模版,就A了,上题解 题意:M个猪圈,N个顾客,每个顾客有一些的猪圈的钥匙,只能购买这些有钥匙的猪圈里的猪,而且要买一定数量的猪,每个猪圈有已知数量的猪,但是猪圈可以重新打开,将猪的个数,重新分配,以达到卖出的猪的数量最多. 思路:刚学网络流,表示很菜很菜很菜~~①构造网络,将顾客看成源点和汇点以外的结点,并设另外两个节点:源点和汇点.②源点和每个猪圈的第一个顾客连边,边的权是开始时候猪圈中猪的数量.③ 若源点和某个节点之间有重边,则将权合并

解题报告 之 POJ1149 PIGS

解题报告 之 POJ1149 PIGS 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-house

POJ 1149 PIGS 最大流

第一次做网络流,看着教材里面的题解做的= = 用的是Ford,应该是最好理解的把,就是不断的找有没有从源点到汇点的增广路然后更新. 建图真是难啊,而且感觉细节要注意的地方比较多,一开始没有考虑反向弧,WA了两发,sad... #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <strin

POJ 1149 PIGS(最大流+建图)

题目链接:http://poj.org/problem?id=1149 题意:M个猪圈,N个顾客,每个顾客有一些的猪圈的钥匙,只能购买能打开的猪圈里的猪,而且要买一定数量的猪,每个猪圈有已知数量的猪, 但是猪圈可以重新打开,将猪的个数,重新分配,但是只能将猪往当前打开状态的猪圈里赶,以达到卖出的猪的数量最多. 思路:还是4部分,源点->猪圈->猪圈->汇点 Accepted 976K 63MS C++ 能用EK水的,当然用EK水 #include <iostream> #in

POJ1149 PIGS 【最大流】

PIGS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16555   Accepted: 7416 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 t

POJ1149.PIGS(迈克卖猪问题)——最大流

http://poj.org/problem?id=1149 题目描述: 迈克在一个养猪场工作,养猪场里有M 个猪圈,每个猪圈都上了锁.由于迈克没有钥匙,所以他不能打开任何一个猪圈.要买猪的顾客一个接一个来到养猪场,每个顾客有一些猪圈的钥匙,而且他们要买一定数量的猪.某一天,所有要到养猪场买猪的顾客,他们的信息是要提前让迈克知道的.这些信息包括:顾客所拥有的钥匙(详细到有几个猪圈的钥匙.有哪几个猪圈的钥匙).要购买的数量.这样对迈克很有好处,他可以安排销售计划以便卖出的猪的数目最大.更详细的销售