poj 1149 建图+最大流

来源:互联网 发布:2015最流行的网络歌曲 编辑:程序博客网 时间:2024/06/06 08:56

此题关键问题在于顾客是一个接一个来的,所以早来的顾客选择权越大。

下面是建图

1、首先将所有顾客和汇点连接,边容量就是顾客需要的猪的数量。这是很容易想到的。

2、然后,对于某个猪圈,最先来的人能最先访问它,所以猪圈(源)优先连接先来的人,边容量为猪圈里猪的数目,如果当前猪圈已经被访问过,那么就让上一次访问这个猪圈的顾客和当前顾客连接。

上图的最大流就是答案。

可以这样想象,猪优先给,先打开它的人,晚来的人只能拿上一个人剩下来的(因为上一个人拿完他的那一份,流量就流向了汇点)。


#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<set>#include<map>#include<queue>#include<vector>#include<string>#define eps  1e-12#define INF   0x7fffffff#define maxn 1500using namespace std;int n,m;int en;int st,ed;//源点和汇点int dis[maxn] ;//dis[i],表示  到 原点  s 的 层数int que[9999999];struct edge{int to,c,next;};edge e[9999999];int head[maxn];void add(int a,int b,int c){e[en].to=b;e[en].c=c;e[en].next=head[a];head[a]=en++;e[en].to=a;e[en].c=0;e[en].next=head[b];head[b]=en++;}int bfs(){    memset(dis,-1,sizeof(dis));    dis[st]=0;    int front=0,rear=0;    que[rear++]=st;    while(front<rear)    {        int j=que[front++];        for(int k=head[j];k!=-1;k=e[k].next)        {            int i=e[k].to;if(dis[i]==-1&&e[k].c)            {                dis[i] = dis[j]+ 1 ;                que[rear++]=i;                if(i==ed) return true;            }        }    }    return false;}int dfs(int x,int mx){    int i,a;    if(x==ed) return mx ;    int ret=0;    for(int k=head[x];k!=-1&&ret<mx;k=e[k].next)    {        if(e[k].c&&dis[e[k].to]==dis[x]+1)        {            int dd=dfs(e[k].to,min(e[k].c,mx));            e[k].c-=dd;            e[k^1].c+=dd;            mx-=dd;            ret+=dd;        }    }    if(!ret) dis[x]=-1;    return ret;}void init(){    en=0;st=n+m+1;     //源    ed=n+m+2;     //汇memset(head,-1,sizeof(head));}int key[maxn],pig[maxn];int v[maxn];int c[400][400];void build(){    int x,y;    memset(c,0,sizeof(c));    memset(v,0,sizeof(v));    for(int i=1;i<=m;i++)    {        scanf("%d",&pig[i]);    }    for(int i=1;i<=n;i++)    {        scanf("%d",&x);        for(int j=1;j<=x;j++)        {            scanf("%d",&key[j]);            if(!v[key[j]])            {                v[key[j]]=i;                add(st,i,pig[key[j]]);            }            else            {                add(v[key[j]],i,INF);                v[key[j]]=i;            }        }        scanf("%d",&y);        add(i,ed,y);    }}int dinic(){    int tmp=0;    int maxflow=0;    while(bfs())    {        while(tmp=dfs(st,INF)) maxflow+=tmp;    }    return maxflow;}int main(){    while(scanf("%d%d",&m,&n)!=EOF)    {        init();        build();        printf("%d\n",dinic());    }}


4 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 教会的事情商量是起冲突怎么办 转转购买的产品是坏的怎么办 二年级的学生反应太迟钝怎么办? 特别胖的人运动一半体力不支怎么办 怀孕了在胸透门口站了很久怎么办 自己觉的色弱但高考体检正常怎么办 高考体检不合格怎么办会影响录取吗 老婆起诉我离婚我不想离怎么办 中考结束了成绩差的学生怎么办 我儿了眼角模不好了怎么办 打了2次催产针没反应怎么办 高中体检学生隐私被同学看到怎么办 要出去旅游刚好遇上月经期怎么办 兵检的时候还在高中怎么办 人流后带上环20天白带很黄怎么办 武警义务兵训练的时候没合格怎么办 小孩考试考的不好·家长怎么办 怀孕了不小心碰了屁股疼怎么办 新密职教中心开学军训有点慌怎么办 房产证是士兵证办的退伍后怎么办 士兵证办的银行卡退伍了怎么办 看左上牙后引发上颌窦炎怎么办 老板克扣进件加班工资应该怎么办 医生给婴儿按嘴巴碰到喉咙痛怎么办 事故逃逸人死对方要钱太多怎么办 毕业工作未满一年辞职档案怎么办 淘宝上买的东西客服不理怎么办 蚂蚁借呗还款后没显示还款怎么办 王者荣耀什么英雄都打的很烂怎么办 军校参加了政审体检误了怎么办 如果老板搬迁不给工人补偿怎么办 下面的毛很多又掉的厉害怎么办? 想去美国开饭店要怎么办签证 在沙漠中旅游如果车子坏了该怎么办 小磨床平面磨出来很粗怎么办 玩cs鼠标单点总是连点怎么办 论文出现计算上的错误该怎么办 不戴头盔违法扣分怎么办不了缴费 去法国会说英语不会说法语怎么办 企业有很多费用没有正式发票怎么办 我二张一万元的作废发票掉了怎么办