平面图求最小割;

其实看bzoj1001一开始着实把我怔住了

AC的人暴多,可自己完全没思路

后来看了某大牛的ppt,才会做

一个月前做这题的吧,今天来简单回忆一下;

首先是欧拉公式

如果一个连通的平面图有n个点,m条边和f个面,那么f=m-n+2

我们把原图的每个面看成新图的一个点,对于原图中的每条边

如果边只属于一个面,那么给对应点连一个自环;

如果边两侧各有一个面,那么给对应点之间连一条无向边

这样,新图与原图的边一一对应;

可以发现,新图的一条路径对应原图的一个割

于是我们原图起点终点连一条边,增加一个附加面(也可以理解为把外面言直线st分为两个面);

按上述方法建新图,于是最小割问题转化为对新图求最短路;

最短路可以用堆优化dij;

这题我的dij+heap写的有进步

 const inf=;
type link=^node;
     node=record
       po,len:longint;
       next:link;
     end;
     point=record
       num,loc:longint;
     end; var w:array[..] of link;
    heap:array[..] of point;
    where,d:array[..] of longint;
    xie,hen,shu:array[..,..] of longint;
    t,s,i,j,n,m,x,y:longint;
    p:link; procedure swap(var a,b:point);
  var c:point;
  begin
    c:=a;
    a:=b;
    b:=c;
  end; procedure add(x,y,z:longint);
  var p:link;
  begin
    new(p);
    p^.po:=y;
    p^.len:=z;
    p^.next:=w[x];
    w[x]:=p;
  end; procedure up(i:longint);
  var j,x,y:longint;
  begin
    j:=i shr ;
    while j> do
    begin
      if heap[i].num<heap[j].num then
      begin
        x:=heap[i].loc;
        y:=heap[j].loc;
        where[x]:=j;
        where[y]:=i;
        swap(heap[i],heap[j]);
        i:=j;
        j:=i shr ;
      end
      else break;
    end;
  end; procedure sift(i:longint);
  var j,x,y:longint;
  begin
    j:=i shl ;
    while j<=s do
    begin
      if (j+<=s) and (heap[j].num>heap[j+].num) then inc(j);
      if heap[i].num>heap[j].num then
      begin
        x:=heap[i].loc;
        y:=heap[j].loc;
        where[x]:=j;
        where[y]:=i;
        swap(heap[i],heap[j]);
        i:=j;
        j:=i shl ;
      end
      else break;
    end;
  end; procedure build;    //复杂的建图,这种东西一定要谨慎,错误才会少;
  var i:longint;
  begin
    for i:= to m- do
    begin
      add(,i+,hen[,i]);
      add(i+,,hen[,i]);
    end;
    for i:= to n- do
    begin
      x:=(m-)*(*i-)+;
      add(,x,shu[i,m]);
      add(x,,shu[i,m]);
    end;     for i:= to m- do
    begin
      x:=t-m+i;
      add(t,x,hen[n,i]);
      add(x,t,hen[n,i]);
    end;
    for i:= to n- do
    begin
      x:=(m-)*(*i-)+;
      add(t,x,shu[i,]);
      add(x,t,shu[i,]);
    end;     for i:= to n- do
      for j:= to m- do
      begin
        x:=(*i-)*(m-)+j+;
        y:=x+m-;
        add(x,y,hen[i,j]);
        add(y,x,hen[i,j]);
      end;     for i:= to n- do
      for j:= to m- do
      begin
        x:=(*i-)*(m-)+j;
        y:=x+m;
        add(x,y,shu[i,j]);
        add(y,x,shu[i,j]);
      end;     for i:= to n- do
      for j:= to m- do
      begin
        x:=(*i-)*(m-)+j+;
        y:=x+m-;
        add(x,y,xie[i,j]);
        add(y,x,xie[i,j]);
      end;
  end; procedure dij;       //最短路
  var p:link;
      mid,k,y:longint;
  begin
    p:=w[];
    for i:= to t do
      d[i]:=inf;
    d[]:=;
    while p<>nil do
    begin
      x:=p^.po;
      d[x]:=min(d[x],p^.len);
      p:=p^.next;
    end;
    s:=;
    for i:= to t do
    begin
      inc(s);
      heap[s].num:=d[i];
      heap[s].loc:=i;        //表示堆的这个位置是哪个点
      where[i]:=s;           //where表示这个点在堆的哪个位置
      up(s);
    end;     for k:= to t do
    begin
      mid:=heap[].num;
      if s= then break;      
      if mid=inf then break;   
      x:=heap[].loc;
      y:=heap[s].loc;
      where[y]:=;       swap(heap[],heap[s]);   //退堆
      dec(s);       sift();
      p:=w[x];
      while p<>nil do
      begin
        y:=p^.po;
        if d[y]>p^.len+mid then     //更新,入堆
        begin
          d[y]:=p^.len+mid; 
          heap[where[y]].num:=d[y];
          up(where[y]);
        end;
        p:=p^.next;
      end;
    end;
  end; begin
  readln(n,m);
  for i:= to n do
  begin
    for j:= to m- do
      read(hen[i,j]);
  end;
  for i:= to n- do
  begin
    for j:= to m do
      read(shu[i,j]);
  end;
  for i:= to n- do
  begin
    for j:= to m- do
      read(xie[i,j]);
  end;   if n= then       //注意这种情况要特判
  begin
    t:=inf;
    for i:= to m- do
      t:=min(hen[,i],t);
    writeln(t);
    halt;
  end
  else if m= then
  begin
    t:=inf;
    for i:= to n- do
      t:=min(t,shu[i,]);
    writeln(t);
    halt;
  end;
  t:=(n-)*(m-)*+;    //计算新图总点数
  build;
  dij;
  writeln(d[t]);
end.

bzoj1001的更多相关文章

  1. 【bzoj1001】 BeiJing2006—狼抓兔子

    http://www.lydsy.com/JudgeOnline/problem.php?id=1001 (题目链接) 题意 给出一张图,求最小割. Solution1 最小割=最大流,所以直接Din ...

  2. 【BZOJ1001】狼抓兔子(网络流)

    [BZOJ1001]狼抓兔子(网络流) 题面 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨, ...

  3. BZOJ1001 [BeiJing2006]狼抓兔子 最小割 对偶图 最短路

    原文链接http://www.cnblogs.com/zhouzhendong/p/8686871.html 题目传送门 - BZOJ1001 题意 长成上面那样的网格图求最小割. $n,m\leq ...

  4. bzoj1001狼抓兔子 对偶图优化

    bzoj1001狼抓兔子 对偶图优化 链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1001 思路 菜鸡总是要填坑的! 很明显让你求网格图的最 ...

  5. BZOJ1001 BJOI2006狼抓兔子(最小割+最短路)

    显然答案就是最小割.直接跑dinic也能过,不过显得不太靠谱. 考虑更正确的做法.作为一个平面图,如果要把他割成两半,那么显然可以用一条曲线覆盖且仅覆盖所有割边.于是我们把空白区域看成点,隔开他们的边 ...

  6. 【BZOJ1001】[BeiJing2006]狼抓兔子 对偶图最短路

    [BZOJ1001][BeiJing2006]狼抓兔子 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子 ...

  7. 【BZOJ1001】狼抓兔子(平面图转对偶图,最短路)

    [BZOJ1001]狼抓兔子(平面图转对偶图,最短路) 题面 BZOJ 洛谷 题解 这题用最小割可以直接做 今天再学习了一下平面图转对偶图的做法 大致的思路如下: 1.将源点到汇点中再补一条不与任何线 ...

  8. BZOJ1001 BeiJing2006 狼抓兔子 【网络流-最小割】*

    BZOJ1001 BeiJing2006 狼抓兔子 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较 ...

  9. 【bzoj1001】【最短路】【对偶图】【最大流转最小割】狼抓兔子题解

    [BZOJ1001]狼抓兔子 1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 18872  Solved ...

随机推荐

  1. android 软件开机自启动

    安卓的很多功能实现方式都是“Don't call me, I'll call you back!”,开机启动就是其中之一 步骤: 1.首先建立一个BroadcastReceiver, 2.在他的onR ...

  2. 51nod1264线段相交

    1264 线段相交 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 给出平面上两条线段的两个端点,判断这两条线段是否相交(有一个公共点或有部分重合认为相交). 如果相交, ...

  3. Python urllib2 模块学习笔记

    2015.3.6  urllib2的使用方法大致如下 # 定制Handler处理函数 opener = urllib2.build_opener(ProxyHandler, HTTPHandler) ...

  4. LR中错误代号为27796的解决方法

    问题:   曾经遇到过一个问题,在一次性能测试过程中,使用http协议的多用户向服务器发送请求.设置了持续时间,出现错误为:27796, Failed to connect to server 'ho ...

  5. PythonCrawl自学日志(3)

    2016年9月21日09:21:431.爬虫的抓取周期:(1)首先生成初始请求爬第一个url,并指定一个回调函数被称为与下载这些请求的响应.(2)第一个请求执行通过调用 start_requests( ...

  6. C语言创建一个窗口提示

    打开Vs2012[我的是2012] /* X下面这些东西并没有什么用... 就不改了用2013 2015都一样 当然 devC++ 还有最原始的那个vc6.0也都是可以的. 编译环境遇到了相关问题网上 ...

  7. Google code: Why ‘Everything up-to-date’ when pushing (git)

    原文链接:http://blog.rexzhao.com/2011/11/28/google-code-git-everything-up-to-date-when-push.html 第一次在Goo ...

  8. Mac技巧之让U盘、移动硬盘在苹果电脑和Windows PC都能识别/读写,且支持4GB大文件:exFAT格式

    如果您的 U 盘.移动硬盘既要用于 PC 又要用于苹果电脑,Mac OS X 系统的 HFS+ 和 Windows 的 NTFS 格式显然都不行……HFS+ 在 Windows 下不识别,NTFS 格 ...

  9. Ubuntu上部署C# 网站 步骤简单记录

    对于刚接触linux的同学,由于命令不熟悉,所以要想在上面部署C#网站,容易迷茫,可以参考此简易步骤: 安装 mono: apt-get install mono  按tab搜索 找到mono相关的组 ...

  10. MyISAM读写并发优化

    MyISAM在读操作占主导的情况下是很高效的.可一旦出现大量的读写并发,同InnoDB相比,MyISAM的效率就会直线下降,而 且,MyISAM和InnoDB的数据存储方式也有显著不同:通常,在MyI ...