PIGS POJ

来源:互联网 发布:php twitter 登陆sdk 编辑:程序博客网 时间:2024/06/16 19:15

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
题意:每个人想买猪2333,然后由m个猪圈,一个人会挑固定几个猪圈打开,然后从里面挑猪,被打开的猪圈可以随便改变猪的个数,只要总和不变即可.
建图思路:把每个顾客看成节点,将源点会第一个打开猪圈的顾客连起来,权值是顾客会第一次打开的猪圈中猪的总和,后面打开猪圈的顾客可挑选的猪相当于前一个顾客挑剩的总和.所以把前一个打开猪圈的人和当前打开的人连一条INF的边,最后所有人和汇点连一条边就好了 23333 建图还是巧妙啊QWQ

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<string>#include<vector>#include<set>#include<queue>#include<map>#include<sstream>#include<stack>#include<functional>#include<cctype>using namespace std;typedef long long ll;//thanks to pyf ...//thanks to lmd ...#define INF 0x3f3f3f3f#define CLR(a,b) memset(a,b,sizeof(a))const int N = 5005;struct Edge{    int from,to,cap,flow;    Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}};struct Dinic{    int n,m,s,t;    vector<Edge>edges;    vector<int>G[N];    bool vis[N];    int d[N];    int cur[N];    void add_edge(int u,int v,int cap)    {        edges.push_back(Edge(u,v,cap,0));        edges.push_back(Edge(v,u,0,0));        int m = edges.size();        G[u].push_back(m-2);        G[v].push_back(m-1);    }    bool bfs()    {        memset(vis,0,sizeof(vis));        queue<int>q;        q.push(s);        d[s] = 0;        vis[s] = 1;        while(!q.empty())        {            int x = q.front();            q.pop();            for(int i=0;i<G[x].size();i++)            {                Edge &e = edges[G[x][i]];                if(!vis[e.to]&&e.cap > e.flow)                {                    vis[e.to] = 1;                    d[e.to] = d[x] +1;                    q.push(e.to);                }            }        }        return vis[t];    }    int dfs(int x,int a)    {        if(x==t||a==0)            return a;        int flow = 0,f;        for(int &i = cur[x];i<G[x].size();i++)        {            Edge &e = edges[G[x][i]];            if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0)            {                e.flow += f;                edges[G[x][i]^1].flow -= f;                flow += f;                a-=f;                if(!a)                    break;            }        }        return flow;    }    int Maxflow(int s,int t)    {        this -> s = s,this -> t = t;        int flow = 0;        while(bfs())        {            CLR(cur,0);            flow+= dfs(s,INF);        }        return flow;    }};int pig[N];int vis[N];int used[N];int main(){    int n,m;    while(scanf("%d%d",&n,&m)==2)    {        Dinic ans;        int s = 0;        int t = m+1;        CLR(vis,0);        for(int i=1;i<=n;i++)        {            scanf("%d",pig+i);        }        for(int i=1;i<=m;i++)        {            int cnt;            int cap = 0;            CLR(used,0);            scanf("%d",&cnt);            for(int j=0;j<cnt;j++)            {                int id;                scanf("%d",&id);                if(!vis[id])                {                    vis[id] = i;                    cap+=pig[id];                }                else                {                    if(!used[vis[id]])                        ans.add_edge(vis[id],i,INF);                    vis[id] = i;                }            }            if(cap)                ans.add_edge(s,i,cap);            int need;            scanf("%d",&need);            ans.add_edge(i,t,need);        }        printf("%d\n",ans.Maxflow(s,t));    }}
0 0
原创粉丝点击