poj 1149 PIGS(网络流dinic)

PIGS

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 16054   Accepted: 7185

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

构图的时候把掌管有同一个猪圈的两个人由先到的向后到的引一条无限流量的边!

#include"stdio.h"
#include"string.h"
#include"math.h"
#include"queue"
#include"algorithm"
using namespace std;
#define N 1500
#define min(a,b) (a<b?a:b)
const int inf=0x7fffffff;
int c[N][N],head[N],cnt;
int dis[N],q[N];
struct node
{
    int u,v,w,next;
}map[N*100];
void add(int u,int v,int w)
{
    map[cnt].u=u;
    map[cnt].v=v;
    map[cnt].w=w;
    map[cnt].next=head[u];
    head[u]=cnt++;
    map[cnt].u=v;
    map[cnt].v=u;
    map[cnt].w=0;
    map[cnt].next=head[v];
    head[v]=cnt++;
}
int bfs(int n)
{
    int s=0,t1,t2,x,v,i;
    memset(dis,0,sizeof(dis));
    t1=t2=0;
    q[t1++]=s;
    dis[s]=1;
    while(t2<t1)
    {
        x=q[t2++];
        for(i=head[x];i!=-1;i=map[i].next)
        {
            v=map[i].v;
            if(map[i].w&&!dis[v])
            {
                dis[v]=dis[x]+1;
                if(v==n)
                    return 1;
                q[t1++]=v;
            }
        }
    }
    return 0;
}
int dfs(int s,int n,int lim)
{
    int t=n,i,v,tmp,cost=0;
    if(s==t)
        return lim;
    for(i=head[s];i!=-1;i=map[i].next)
    {
        v=map[i].v;
        if(map[i].w&&dis[v]==dis[s]+1)
        {
            tmp=dfs(v,n,min(lim-cost,map[i].w));
            if(tmp>0)
            {
                map[i].w-=tmp;
                map[i^1].w+=tmp;
                cost+=tmp;
                if(cost==lim)
                    break;
            }
            else
                dis[v]=-1;
        }
    }
    return cost;
}
int dinic(int n)
{
    int ans=0,s=0;
    while(bfs(n))
        ans+=dfs(s,n,inf);
    return ans;
}
int main()
{
    int b,q[N],i,j,k,l,n,m;
    int a[N];
    while(scanf("%d%d",&m,&n)!=-1)
    {
        memset(head,-1,sizeof(head));
        cnt=0;
        for(i=1;i<=m;i++)
        {
            scanf("%d",&a[i]);
            add(0,i,a[i]);
        }
        for(i=1;i<=n;i++)
        {
            scanf("%d",&q[i]);  //客户拿的钥匙数目
            for(j=1;j<=q[i];j++)   //猪舍
            {
                scanf("%d",&k);  //能打开的猪舍
                c[i][j]=k;
                add(k,m+i,a[k]);
            }
            scanf("%d",&b);
            add(m+i,m+n+1,b);
            for(j=1;j<i;j++) //寻找该客户之前的客户是否能打开同一个猪舍
            {
                int flag=0;
                for(k=1;k<=q[j];k++)  //某个客户能打开的猪舍
                {
                    for(l=1;l<=q[i];l++)//第I个客户能打开的猪舍
                    {
                        if(c[j][k]==c[i][l])
                        {
                            add(j+m,i+m,inf);  //建一条无限流量的边
                            flag=1;
                            break;
                        }
                    }
                    if(flag)
                        break;
                }
            }
        }
        printf("%d\n",dinic(n+m+1));
    }
    return 0;
}

poj 1149 PIGS(网络流dinic)

时间: 2024-10-06 20:44:57

poj 1149 PIGS(网络流dinic)的相关文章

POJ 1149 PIGS(Dinic最大流)

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

POJ 1149 PIGS ( 网络流 )

主要是建图有些小烦,若几个节点流量的来源或者去向完全相同,且流量为 INF,将它们合并成一个节点. 若从两点间有且仅有一条容量为 INF 的边,将两点合并成一个节点. #include <iostream> #include <cstring> #include <queue> using namespace std; const int INF = 0x7fffffff; const int MAXN = 110; int capacity[MAXN][MAXN],

POJ 1149 PIGS 迈克卖猪问题 网络流构图+三种AC方法

题目链接:POJ 1149 PIGS PIGS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16533   Accepted: 7403 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 key

POJ 1149 PIGS(最大流)

POJ 1149 PIGS 题目链接 题意:有n个猪圈,m个顾客,猪圈中一开始有一些猪,顾客轮流来(注意是有先后顺序的),然后每个顾客会开启一些猪圈,在开启的猪圈中最多买b只猪,之后可以任意把剩下的猪分配到开着的猪圈中,问最多能卖出几只猪 思路:这题的关键在于建模,由于顾客有先后顺序,假如后来的顾客会开启x门,前面一个顾客也会开启x门,那么前面顾客相当与可以分配给后面顾客, 所以建模的方式为,源点和每个猪圈连,容量为猪圈猪数,每个猪圈和第一个开的顾客连,如果后面有顾客会开这个猪圈,则和之前的顾客

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

POJ 1149 PIGS (网络最大流 Dinic 建对图你就赢了)

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

POJ 1149 PIGS 【网络流】

题意: m n   //有m个猪圈,n个人卖猪. a1...am    //编号为i的猪圈里有ai头猪. b1 c1...cb1 d1   //第i个人有bi把钥匙,分别是ci猪圈的,其它猪圈里的猪都是锁着的   他最多买di头猪 . . . bn c1...cbn dn 注意的是假如某买主有第一和第二个猪圈的钥匙,那么他买完猪以后这两个猪圈的个数我们可以随意调整,调整完将猪圈锁上. 求:最多能卖多少猪 思路: 源点到每个猪圈建边,容量为这个猪圈的猪的数量,然后买主与他有钥匙的猪圈建边,容量in

网络流(最大流):POJ 1149 PIGS

PIGS Time Limit: 1000ms Memory Limit: 10000KB This problem will be judged on PKU. 64-bit integer(整数) IO format: %lld      Java class name: Main Mirko works on a pig farm that consists of M locked pig-houses and Mirko can't unlock any pighouse because