正如学长在一个月前跟我说的,网络流千变万化,在regional这个级别的比赛中经常出现,最小割模型就是其中一个。

其实我也是很早就知道最小割,但是我只是知道最小割等于最大流这个简单的定理。然后那时单纯的认为最小割嘛,跑一个最大流就行了,有什么难的……

然而,在一周以前,我认为最小割让人感到难的或许不是算法,而是构图,因为之前碰到的植物大战僵尸的最大权闭合子图。这个题就是灵活运用最小割的概念取推理证明了很多定理,进而把题目转化成了不容易看出来的最小割。

知道我做了这道题,才发现,最小割完全可以用一个完全不同的方法实现。先说说当时的背景吧。我们程序设计老师让我们做ccf的前三道题目,我嘛一向在程设这种课上不听指挥,自己跑去看最后一道题目。发现17年三月的题目是一道裸的网络流(最小割),但是惊人的发现有快2500W个点,根本破不了。于是去找队友帮忙,然后他就告诉我这道题,又被教育了一波……这是一道很老但是很经典的题目:

1001: [BeiJing2006]狼抓兔子

Time Limit: 15 Sec  Memory Limit: 162 MB
Submit: 21787  Solved: 5480
[Submit][Status][Discuss]

Description

现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,
而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:

左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 
1:(x,y)<==>(x+1,y) 
2:(x,y)<==>(x,y+1) 
3:(x,y)<==>(x+1,y+1) 
道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,
开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下解(N,M)的窝中去,狼王开始伏击
这些兔子.当然为了保险起见,如果一条道路上最多通过的兔子数为K,狼王需要安排同样数量的K只狼,
才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的
狼的数量要最小。因为狼还要去找喜羊羊麻烦.

Input

第一行为N,M.表示网格的大小,N,M均小于等于1000.
接下来分三部分
第一部分共N行,每行M-1个数,表示横向道路的权值. 
第二部分共N-1行,每行M个数,表示纵向道路的权值. 
第三部分共N-1行,每行M-1个数,表示斜向道路的权值. 
输入文件保证不超过10M

Output

输出一个整数,表示参与伏击的狼的最小数量.

Sample Input

3 4
5 6 4
4 3 1
7 5 3
5 6 7 8
8 7 6 5
5 5 5
6 6 6

Sample Output

14
        相信你很容易看出来,参与伏击的狼最少,无疑是选取边集,使得边把网络切断且权值最小,这就刚好是最小割的定义。但是这题的数据最多100W个点(相比于ccf的题目数据还更弱?!)。普通的网络流肯定超时(据说dinic可以水过?!)。那么我们只能换个思路去做。我记得当时队友点拨我时,说把图转向,然后求最短路,当时瞬间有种恍然大悟的感觉,的确,确实比较好理解。如果我能通过一些最短的边把整个网络切断,那么这个边之和必定是最小割。但是背后的具体建图还有理论依据也很值得探讨。
        这个问题的本源还是可以追溯到大神的论文。周冬《两极相通——浅析最大—最小定理在信息学竞赛中的应用》
        正如大神所说的,根据欧拉公式,如果平面图有n个点,m条边,f个面,那么三个数字之前的关系满足f=m-n+2。那么如果对于同一幅图,我们如果把点和面对调,等到式子n=m-f+2,发现仍然满足欧拉公式。即重新构图,把面变为点,点变为面,边不变,得到的图仍然是平面图,我们称这样的图为原图的对偶图。然后,关于对偶图的边的问题,如果有一条边是原图两面的分界线,那么在对偶图中,它就是连接两个面对应点的边(相当于把边旋转了90°)。
        注意到我把那个旋转标记了出来,因为这个旋转可以形象的代表我在原来的边上切了一刀,把原来的边割开了。那么,如果我们能够在对偶图中找到一组边把整个图中间切断,那么这组边就构成了一个割。既然要求最小割,那么我们边把对偶图中旋转过来的边的权值赋值为与原边一样。
        那么,现在就要解决起点和终点的问题了。注意到,既然原图是平面图,那么它一定是有边界的,很显然,最小割一定是从图的一个边界贯穿到另外一个边界的,哦对,这里我默认起点和终点把整幅图以及图外的平面区域分成了两个部分。最小割一定能从一部分的外边界贯穿到另一部分的外边界。依然如此,我们就把原图中所有的外边界上的边连上起点和终点。这样,如果我们从起点到重点跑一遍最短路,那么求出来的就是最小割了。这个复杂度可是一下子降了很多,千万的数据理论上用dijkstra都不成问题。
        至于本题的话,就是把方格图左边界和下边界与起点(终点)相连,右边界和上边界与终点(起点)相连,其他的按照我说的对偶图的转换方式转换成对偶图,再跑一遍最短路即可。具体代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<queue>
#define LL long long
#define INF 2147483647
#define MAX_V 2001000using namespace std;int num[1010][1010][2],d[MAX_V];
int m,n,p=0,s,t;struct Edge
{int y,w;
};struct cmp
{bool operator()(int a,int b){return d[a]>d[b];}
};priority_queue<int,vector<int>,cmp> q;
vector<Edge> g[MAX_V];
bool v[MAX_V];inline void dijkstra(int s)
{for(int i=1;i<=t;i++){v[i]=0; d[i]=INF;}d[s]=0;q.push(s);while (!q.empty()){int j=q.top(); q.pop();if (v[j]) continue; v[j]=1;for(int k=0;k<g[j].size();k++)if (d[g[j][k].y]>d[j]+g[j][k].w){d[g[j][k].y]=d[j]+g[j][k].w;q.push(g[j][k].y);}}
}inline void addedge(int x,int y,int w)
{Edge node;node.y=y;node.w=w;g[x].push_back(node);
}int main()
{scanf("%d%d",&n,&m);if (n==1||m==1){int ans=INF;for(int i=1;i<max(n,m);i++){int x; scanf("%d",&x); ans=min(ans,x); }printf("%d\n",ans);return 0;}for(int i=1;i<n;i++)for(int j=1;j<m;j++){num[i][j][0]=++p;num[i][j][1]=++p;}s=++p; t=++p;for(int i=1;i<=n;i++)for(int j=1;j<m;j++){int x; scanf("%d",&x);if (i==1) addedge(num[i][j][1],t,x);if (i==n) addedge(s,num[i-1][j][0],x);if (i!=n&&i!=1){addedge(num[i-1][j][0],num[i][j][1],x);addedge(num[i][j][1],num[i-1][j][0],x);}}for(int i=1;i<n;i++)for(int j=1;j<=m;j++){int x; scanf("%d",&x);if (j==1) addedge(s,num[i][j][0],x);if (j==m) addedge(num[i][j-1][1],t,x);if (j!=m&&j!=1){addedge(num[i][j-1][1],num[i][j][0],x);addedge(num[i][j][0],num[i][j-1][1],x);}}for(int i=1;i<n;i++)for(int j=1;j<m;j++){int x; scanf("%d",&x);addedge(num[i][j][0],num[i][j][1],x);addedge(num[i][j][1],num[i][j][0],x);}dijkstra(s);printf("%d\n",d[t]);return 0;
}

平面图最小割 BZOJ 2006相关推荐

  1. 洛谷2046 BZOJ2007 NOI2010 海拔 平面图最小割

    题目链接 题意: 给你一个网格图,正反边边权不同,从海拔低的地方到海拔高的地方的代价是海拔差乘边权,海拔高到海拔低的地方不需要代价.左上角海拔是0,右下角海拔是1,让你任意安排其他点的海拔,使得每条边 ...

  2. [国家集训队]happiness 最小割 BZOJ 2127

    题目描述 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文 ...

  3. hdu3870——平面图最小割

    2008OI论文原题-周冬<两极相通--浅析最大-最小定理在信息学竞赛中的应用> 可以转化为最短路径问题- 方法讲的很详细,就不再写了-注意这种方法只能针对s, t在平面图最外层边上的情况 ...

  4. 模板 - 最小割(常见最小割题型技巧总结)

    整理的算法模板合集: ACM模板 目录 一.集合划分模型 二.点边转化 三.最小割的可行边与必须边 四.二分图的可行边和必须边 五.平面图最小割 六.最小割的一些小技巧 1.记录划分方案 2.求割边数 ...

  5. [2018.3.30集训]path-对偶图-最小割

    题目大意 给出一个包含 n + 1 个结点的有向图,结点的编号为 0 到 n.图中有 m 条 有向边,第 i 条有向边起点为 ui,终点为 vi,且长度为 wi.并且这些边还满 足如下的性质: • 对 ...

  6. hdu3035 最小割转换成最短路

    题意:       给你一个平面图,要求从求出从左上角到右下角的最小割. 思路:       如果大意的可能直接上来一遍最大流,然后就会各种悲剧的MLE,TLE,其实这个题目可以用到有个论文里面的那个 ...

  7. S-T平面图中利用最短路求最小割(BZOJ 1001)

    BZOJ 1001: [BeiJing2006]狼抓兔子 最小割 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 现在小朋友们最喜欢 ...

  8. 【BZOJ - 1001】狼抓兔子(无向图网络流,最小割,或平面图转对偶图求最短路SPFA)

    题干: 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: ...

  9. BZOJ 2132 圈地计划(最小割)【BZOJ 修复工程】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2132 是 hydro 的 BZOJ ...

  10. BZOJ 1001: [BeiJing2006]狼抓兔子【最大流/SPFA+最小割,多解】

    1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MB Submit: 23822  Solved: 6012 [Submit ...

最新文章

  1. ASP.NET MVC以ModelValidator为核心的Model验证体系: ModelValidator
  2. Android初级开发笔记-- activity启动模式的学习(1)
  3. HDU-4059 The Boss on Mars 容斥定理
  4. [WPF]WPF开发方法论
  5. NumPy - np.meshgrid()
  6. 大白话Pyramid Vision Transformer
  7. Flutter CupertinoSliverRefreshControl 苹果风格的刷新效果
  8. Android 系统(49)---Android获取窗口可视区域大小: getWindowVisibleDisplayFrame()
  9. 【零基础学Java】—throw关键字(四十六)
  10. android长按非控件处,Android常用之Butterknife使用详解
  11. DialogBox和DialogBoxParam函数
  12. Ubuntu Julia环境安装教程
  13. c语言求成绩标准差,C语言中求和、计算平均值、方差和标准差的实例
  14. 服务器系统2016开始菜单,大法将致:将Windows Server 2016打造成个人办公系统,WIN2016打造成超级WIN10,WIN2016优化设...
  15. 【转载】租房被骗,选择忍让,成就黑中介的猖狂
  16. linux下查看服务器的cpu、内存大小、硬盘大小
  17. Java程序为身份证照片添加马赛克
  18. kindle 更新_如何手动更新您的Kindle
  19. 用html编写诗句春晓,唐诗与灯谜1:《春晓》
  20. easyrecovery数据恢复软件V15最新版本介绍

热门文章

  1. ClickHouse遇见RoaringBitmap
  2. 基于ESP32CAM的物联网相机系统⑧(用原生JavaWeb实现双摄像头WIFI图传)
  3. 电脑共享手机连接的WiFi
  4. 在Vue中如何缓存页面
  5. 无锡高二计算机会考内容,无锡期中考试卷分析,看一看高一高二高三数学都考了哪些...
  6. busybox制作的rootfs,启动脚本修改定制
  7. 友盟统计前台页面图表或文字的隐藏方法
  8. 《英语语法新思维初级教程》学习笔记(八)一般时态
  9. 小武与YOLOv3 ---- 优图代码
  10. oracle nlv 全称,oracle: OCA-047-题解与实验(9)--SQL语句中COUNT和NLV的用法