Bzoj 1280: Emmy卖猪pigs

 

1280: Emmy卖猪pigs

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 279  Solved: 182
[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

仅包含一个整数,即最多能卖出去的猪的数目。

Sample Input

3 3
3 1 10
2 1 2 2
2 1 3 3
1 2 6

Sample Output

7

HINT

1 ≤ M ≤ 1000
1 ≤ N ≤ 100

【网络流建模汇总T1】

 

 

/**************************************************************
    Problem: 1280
    User: gryz2016
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:2472 kb
****************************************************************/

//S向第一个打开某猪圈的人连边,容量为这个猪圈里猪的数量
//后边的打开这个猪圈的人从第一个打开这个猪圈的人那里连边过来,容量为INF
//因为猪圈里的猪是可以随意调动的嘛 
//然后更新打开这个猪圈的人
//不更新不是不对,但是会慢 
//然后这个人向汇点连边,容量为他要买的猪的数量 

//画个图会很清晰。 
  
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
  
int n,m;
int head[105],from[105],num_edge;
int last[1005];
int w[1005];
int dep[105];
struct Edge
{
    int v,flow,nxt;
}edge[100005];
  
inline int read()
{
    char c=getchar();int num=0,f=1;
    for(;!isdigit(c);c=getchar())
        f=c=='-'?-1:f;
    for(;isdigit(c);c=getchar())
        num=num*10+c-'0';
    return num*f;
}
  
inline void add_edge(int u,int v,int w)
{
    edge[++num_edge].v=v;
    edge[num_edge].flow=w;
    edge[num_edge].nxt=head[u];
    head[u]=num_edge;
}
  
inline bool bfs()
{
    for(int i=0;i<=n;++i)
        from[i]=head[i],dep[i]=0;
    queue<int> que;
    int now,v;
    dep[0]=1;
    que.push(0);
    while(!que.empty())
    {
        now=que.front(),que.pop();
        for(int i=head[now];i;i=edge[i].nxt)
        {
            v=edge[i].v;
            if(!dep[v]&&edge[i].flow)
            {
                dep[v]=dep[now]+1;
                if(v==n)
                    return 1;
                que.push(v);
            }
        }
    }
    return 0;
}
  
int dfs(int now,int flow)
{
    if(now==n||!flow)
        return flow;
    int outflow=0,v,tmp;
    for(int &i=from[now];i;i=edge[i].nxt)
    {
        v=edge[i].v;
        if(dep[v]!=dep[now]+1)
            continue;
        tmp=dfs(v,min(flow,edge[i].flow));
        flow-=tmp;
        outflow+=tmp;
        edge[i].flow-=tmp;
        edge[i^1].flow+=tmp;
        if(!flow)
            return outflow;
    }
    dep[now]=0;
    return outflow;
}
  
int main()
{
    num_edge=1;
    m=read(),n=read();
    for(int i=1;i<=m;++i)
        w[i]=read();
    int a,b;
    for(int i=1;i<=n;++i)
    {
        a=read();
        while(a--)
        {
            b=read();
            if(!last[b])    //这个猪圈是第一次被打开 
                add_edge(0,i,w[b]),
                add_edge(i,0,0);
            else
                add_edge(last[b],i,0x7fffffff),        //向上一个打开这个猪圈的人连边 
                add_edge(i,last[b],0);
            last[b]=i;
        }
        b=read();
        add_edge(i,n+1,b);
        add_edge(n+1,i,0);
    }
    ++n;
    int ans=0;
    while(bfs())
        ans+=dfs(0,0x7fffffff);
    printf("%d",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/lovewhy/p/8625892.html