POJ-1149-PIGS(最大流)

来源:互联网 发布:移动宽带端口扩容申请 编辑:程序博客网 时间:2024/06/16 01:01

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 33 1 102 1 2 22 1 3 31 2 6

Sample Output

7



最大流问题,难点在于建边:

#include <iostream>#include <cstdio>#include <cstring>#include <stack>#include <queue>using namespace std;#define MAXN 2005#define INF 0x3f3f3f3fint val[MAXN],vis[MAXN];int head[MAXN],index;struct node{    int v,next,val;}edge[MAXN];void add_edge(int a,int b,int val){    edge[index].v=b;    edge[index].val=val;    edge[index].next=head[a];    head[a]=index++;    edge[index].v=a;    edge[index].val=0;    edge[index].next=head[b];    head[b]=index++;}int deep[MAXN];bool BFS(int start, int end){    memset(deep,0,sizeof(deep));    queue<int> s;    while(!s.empty())s.pop();    s.push(start);    deep[start]=1;    while(!s.empty())    {        int u=s.front();        s.pop();        if(u==end)return 1;        for(int i=head[u]; i!=-1; i=edge[i].next)        {            int v=edge[i].v;            if(!deep[v]&&edge[i].val>0)            {                deep[v]=deep[u]+1;                s.push(v);            }        }    }    return 0;}int DFS(int start, int min_val, int end){    int i,j;    int ans=0;    if(start==end)return min_val;    for(i=head[start]; i!=-1 && ans<min_val; i=edge[i].next)    {        int v=edge[i].v;        if(deep[start]+1==deep[v] && edge[i].val>0)        {            int f=DFS(v,min(min_val-ans,edge[i].val),end);            edge[i].val-=f;            edge[i^1].val+=f;            ans+=f;            if(ans==min_val)return ans;        }    }    return ans;}int DINIC(int start, int end){    int ans=0,t;    while(BFS(start,end))    {        while(t=DFS(start,INF,end))            ans+=t;    }    return ans;}int main(){    int n,m,v,num;    while(~scanf("%d%d",&m,&n))    {        index=0;        memset(vis,0,sizeof(vis));        memset(head,-1,sizeof(head));        for(int i=1; i<=m; ++i)            scanf("%d",&val[i]);        int start=0,end=n+1;        for(int i=1; i<=n; ++i)        {            scanf("%d",&num);            for(int j=0; j<num; ++j)            {                scanf("%d",&v);                if(!vis[v])add_edge(start,i,val[v]);                else add_edge(vis[v],i,INF);                vis[v]=i;            }            scanf("%d",&v);            add_edge(i,end,v);        }        cout<<DINIC(0,n+1)<<endl;    }    return 0;}


0 0