非常非常经典的构图

有二分图学习基础的话,很容易想到这是一个“三分图”的匹配问题

我们将牛,food,drink作为点

为了方便,我们将牛放在中间,每头牛的出边指向drink种类,入边由food指入

建立超级源点指向所有food,超级汇点指向所有drink,

要满足最多的牛,也就是求一个最大流

但注意,如果这样求最大流的话,会经过牛点不止一次(因为牛会有多个入边和多个出边)

所以我们考虑将牛点拆为两个点,中间流量为1,这样就能保证牛只经过1次了

 const max=;
var a:array[..,..] of longint;
    numh,h,cur,pre:array[..] of longint;
    n,t,i,j,m,s,f,d,ans,x:longint; procedure sap;
  var i,j,flow,tmp,neck,u,k:longint;
  begin
    numh[]:=;
    u:=;
    while h[]<t+ do
    begin
      if u=t then
      begin
        i:=;
        j:=cur[];
        flow:=max;
        while i<>t do   //其实这个地方多余了,容易知道,瓶颈边的流量一定为1
        begin
          if flow>a[i,j] then
          begin
            neck:=i;
            flow:=a[i,j];
          end;
          i:=j;
          j:=cur[j];
        end;
        inc(ans,flow);
        i:=;
        j:=cur[i];
        while i<>t do
        begin
          dec(a[i,j],flow);
          inc(a[j,i],flow);
          i:=j;
          j:=cur[i];
        end;
        u:=neck;
      end;
      k:=-;
      for i:= to t do
        if (a[u,i]>) and (h[u]=h[i]+) then
        begin
          k:=i;
          break;
        end;
      if k<>- then
      begin
        cur[u]:=k;
        pre[k]:=u;
        u:=k;
      end
      else begin
        dec(numh[h[u]]);
        if numh[h[u]]= then break;   //GAP优化
        tmp:=t+;
        for i:= to t do
          if (a[u,i]>) then tmp:=min(tmp,h[i]);  //更新标号
        h[u]:=tmp+;
        inc(numh[h[u]]);
        if u<> then u:=pre[u];
      end;
    end;
  end; begin
  readln(n,m,s);
  fillchar(a,sizeof(a),);
  t:=*n+m+s+;     //计算建图后总点数
  for i:= to m do
    a[,*n+i]:=;
  for i:= to s do
    a[*n+m+i,t]:=;
  for i:= to n do
    a[i,i+n]:=;
  for i:= to n do
  begin
    read(f,d);
    for j:= to f do
    begin
      read(x);
      a[*n+x,i]:=;
    end;
    for j:= to d do
    begin
      read(x);
      a[i+n,*n+m+x]:=;
    end;
  end;
  fillchar(cur,sizeof(cur),);
  fillchar(pre,sizeof(pre),);
  fillchar(h,sizeof(h),);
  fillchar(numh,sizeof(numh),);   
  sap;
  writeln(ans);
end.

这题带给我们两个启示:

  1. 拆点和建立超级源汇点是网络流构图的基础而又重要的部分

  2. 网络流的建图比较复杂(这题还算简单),要细心检查……;

poj3281的更多相关文章

  1. POJ3281 Dining —— 最大流 + 拆点

    题目链接:https://vjudge.net/problem/POJ-3281 Dining Time Limit: 2000MS   Memory Limit: 65536K Total Subm ...

  2. Dining(POJ-3281)【最大流】

    题目链接:https://vjudge.net/problem/POJ-3281 题意:厨师做了F种菜各一份,D种饮料各一份,另有N头奶牛,每只奶牛只吃特定的菜和饮料,问该厨师最多能满足多少头奶牛? ...

  3. POJ-3281(最大流+EK算法)

    Dining POJ-3281 这道题目其实也是网络流中求解最大流的一道模板题. 只要建模出来以后直接套用模板就行了.这里的建模还需要考虑题目的要求:一种食物只能给一只牛. 所以这里可以将牛拆成两个点 ...

  4. poj3281 Dining

    Dining Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14316   Accepted: 6491 Descripti ...

  5. POJ3281 Dining(拆点构图 + 最大流)

    题目链接 题意:有F种食物,D种饮料N头奶牛,只能吃某种食物和饮料(而且只能吃特定的一份) 一种食物被一头牛吃了之后,其余牛就不能吃了第一行有N,F,D三个整数接着2-N+1行代表第i头牛,前面两个整 ...

  6. POJ3281 Dining 最大流

    题意:有f种菜,d种饮品,每个牛有喜欢的一些菜和饮品,每种菜只能被选一次,饮品一样,问最多能使多少头牛享受自己喜欢的饮品和菜 分析:建边的时候,把牛拆成两个点,出和入 1,源点向每种菜流量为1 2,每 ...

  7. poj3281(最大流)

    传送门:Dining 题意:一些牛,一些食物,一些饮料,每头牛都有其喜欢的几种食物和几种饮料,求最多能给多少头牛即找到食物又找到饮料~也就是有多少个 牛---食物---饮料 的匹配,而且满足一一匹配, ...

  8. poj-3281(拆点+最大流)

    题意:有n头牛,f种食物,d种饮料,每头牛有自己喜欢的食物和饮料,问你最多能够几头牛搭配好,每种食物或者饮料只能一头牛享用: 解题思路:把牛拆点,因为流过牛的流量是由限制的,只能为1,然后,食物和牛的 ...

  9. poj3281构图题

    题目大意:有F种食物,D种饮料N头奶牛,只能吃某种食物和饮料(而且只能吃特定的一份)一种食物被一头牛吃了之后,其余牛就不能吃了第一行有N,F,D三个整数接着2-N+1行代表第i头牛,前面两个整数是Fi ...

随机推荐

  1. 在Linux上部署和操作Couchbase

    couchbase属于nosql系列,个人感觉它要比mongodb操作简单,mongo的查询语句太复杂.在数据的持久性方面它区别于其他nosql 的唯一大亮点是不受限于其内存分配了多少,只要磁盘空间够 ...

  2. sublime 设置localhost 2

    最近sidebar用不了了,提示更新然后就自动卸载了: 研究了下其他方式实现: Sublime Text 2 Sublime Text 3 都可以使用: 菜单 --> Tools --> ...

  3. Opencv 摄像头矫正

    摄像机有6个外参数(3个旋转,3个平移),5个内参数(fx,fy,cx,cy,θ),摄像机的内参数在不同的视场,分辨率中是一样的,但是不同的视角下6个外参数是变化的,一个平面物体可以固定8个参数,(为 ...

  4. Linux进程间通信IPC学习笔记之消息队列(SVR4)

    Linux进程间通信IPC学习笔记之消息队列(SVR4)

  5. js中的计时器

    在JS中做二级菜单时,被一个鼠标移出时隐藏的小问题困扰了很久. <script> function Menu(id){ var _this=this; this.obj=document. ...

  6. RichTextBox控件-主要用于输入输出编辑文本信息

    1.在RichTextBox控件中添加超链接文字 private void btn_Add_Click(object sender, EventArgs e) { rtbox_HyperLink.Ap ...

  7. poj 2226 Muddy Fields (转化成二分图的最小覆盖)

    http://poj.org/problem?id=2226 Muddy Fields Time Limit: 1000MS   Memory Limit: 65536K Total Submissi ...

  8. 2336: [HNOI2011]任务调度 - BZOJ

    一道随机算法的题目 随便用什么随机算法 首先我们可以想到枚举类型3的最终类型,然后再做 先贪心出一个较优的序列,首先我们知道肯定是在A机器上先做完类型1的事件再做类型2的事件,机器B也类似,因为这些没 ...

  9. JVM内存区域模型

    一:Java技术体系模块图 二:JVM内存区域模型 1.方法区 也称"永久代” .“非堆” ,"perm",  它用于存储虚拟机加载的类信息.常量.静态变量.是各个线程共 ...

  10. hibernate.cfg.xml配置(Oracle+c3p0)

    说明:数据库:Oracle10g:连接池:c3p0 结构: 一.配置hibernate.cfg.xml <?xml version="1.0" encoding=" ...