首先注意到,把一个点的海拔定为>1的数是毫无意义的。实际上,可以转化为把这些点的海拔要么定为0,要么定为1.

其次,如果一个点周围的点的海拔没有和它相同的,那么这个点的海拔也是可以优化的,即把这个点变为周围海拔一样的显然能使结果变优。

于是问题就变成了,这个图的海拔为0的联通块和起点连在一起,海拔为1的联通块和终点连在一起。

此即为经典的最小割。

由于此图为平面图,我们可以使用平面图最小割转对偶图最短路优化算法。

因为这是有向图,因此构建对偶图的时候注意边的方向即可。

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <cstdlib>
  4. # include <iostream>
  5. # include <vector>
  6. # include <queue>
  7. # include <stack>
  8. # include <map>
  9. # include <set>
  10. # include <cmath>
  11. # include <algorithm>
  12. using namespace std;
  13. # define lowbit(x) ((x)&(-x))
  14. # define pi acos(-1.0)
  15. # define eps 1e-
  16. # define MOD
  17. # define INF 1e16
  18. # define mem(a,b) memset(a,b,sizeof(a))
  19. # define FOR(i,a,n) for(int i=a; i<=n; ++i)
  20. # define FO(i,a,n) for(int i=a; i<n; ++i)
  21. # define bug puts("H");
  22. # define lch p<<,l,mid
  23. # define rch p<<|,mid+,r
  24. # define mp make_pair
  25. # define pb push_back
  26. typedef pair<int,int> PII;
  27. typedef vector<int> VI;
  28. # pragma comment(linker, "/STACK:1024000000,1024000000")
  29. typedef long long LL;
  30. int Scan() {
  31. int x=,f=;char ch=getchar();
  32. while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
  33. while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
  34. return x*f;
  35. }
  36. void Out(int a) {
  37. if(a<) {putchar('-'); a=-a;}
  38. if(a>=) Out(a/);
  39. putchar(a%+'');
  40. }
  41. const int N=;
  42. //Code begin...
  43.  
  44. struct Edge{int p, next; LL w;}edge[N*];
  45. struct qnode{
  46. int v; LL c;
  47. qnode(int _v=, LL _c=):v(_v),c(_c){}
  48. bool operator<(const qnode&r)const{return c>r.c;}
  49. };
  50. bool vis[N];
  51. int head[N], cnt=;
  52. LL G1[][], G2[][], G3[][], G4[][], dist[N];
  53. priority_queue<qnode>que;
  54.  
  55. void add_edge(int u, int v, LL w){edge[cnt].p=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++;}
  56. void Dijkstra(int n, int start){
  57. mem(vis,false); FOR(i,,n) dist[i]=INF;
  58. dist[start]=; que.push(qnode(start,));
  59. qnode tmp;
  60. while (!que.empty()) {
  61. tmp=que.top(); que.pop();
  62. int u=tmp.v;
  63. if (vis[u]) continue;
  64. vis[u]=true;
  65. for (int i=head[u]; i; i=edge[i].next) {
  66. int v=edge[i].p; LL cost=edge[i].w;
  67. if (!vis[v]&&dist[v]>dist[u]+cost) dist[v]=dist[u]+cost, que.push(qnode(v,dist[v]));
  68. }
  69. }
  70. }
  71. int main ()
  72. {
  73. int n, s, t, x;
  74. scanf("%d",&n); s=; t=n*n+;
  75. FOR(i,,n) FOR(j,,n) scanf("%lld",&G1[i][j]);
  76. FOR(i,,n) FOR(j,,n) scanf("%lld",&G2[i][j]);
  77. FOR(i,,n) FOR(j,,n) scanf("%lld",&G3[i][j]);
  78. FOR(i,,n) FOR(j,,n) scanf("%lld",&G4[i][j]);
  79. FOR(i,,n) FOR(j,,n) {
  80. if (i==) add_edge(s,i*n+j,G1[i][j]), add_edge(i*n+j,s,G3[i][j]);
  81. else if (i==n) add_edge((i-)*n+j,t,G1[i][j]), add_edge(t,(i-)*n+j,G3[i][j]);
  82. else add_edge((i-)*n+j,i*n+j,G1[i][j]), add_edge(i*n+j,(i-)*n+j,G3[i][j]);
  83. }
  84. FOR(i,,n) FOR(j,,n) {
  85. if (j==) add_edge((i-)*n+j+,t,G2[i][j]), add_edge(t,(i-)*n+j+,G4[i][j]);
  86. else if (j==n) add_edge(s,(i-)*n+j,G2[i][j]), add_edge((i-)*n+j,s,G4[i][j]);
  87. else add_edge((i-)*n+j+,(i-)*n+j,G2[i][j]), add_edge((i-)*n+j,(i-)*n+j+,G4[i][j]);
  88. }
  89. Dijkstra(t,s);
  90. printf("%lld\n",dist[t]);
  91. return ;
  92. }

BZOJ 2007 海拔(平面图最小割转对偶图最短路)的更多相关文章

  1. bzoj2007/luoguP2046 海拔(平面图最小割转对偶图最短路)

    bzoj2007/luoguP2046 海拔(平面图最小割转对偶图最短路) 题目描述: bzoj  luogu 题解时间: 首先考虑海拔待定点的$h$都应该是多少 很明显它们都是$0$或$1$,并且所 ...

  2. BZOJ2007/LG2046 「NOI2010」海拔 平面图最小割转对偶图最短路

    问题描述 BZOJ2007 LG2046 题解 发现左上角海拔为 \(0\) ,右上角海拔为 \(1\) . 上坡要付出代价,下坡没有收益,所以有坡度的路越少越好. 所以海拔为 \(1\) 的点,和海 ...

  3. [BZOJ 2007] [Noi2010] 海拔 【平面图最小割(对偶图最短路)】

    题目链接:BZOJ - 2007 题目分析 首先,左上角的高度是 0 ,右下角的高度是 1.那么所有点的高度一定要在 0 与 1 之间.然而选取 [0, 1] 的任何一个实数,都可以用整数 0 或 1 ...

  4. BZOJ1001/LG4001 「ICPC Beijing2006」狼抓兔子 平面图最小割转对偶图最短路

    问题描述 BZOJ1001 LG4001 题解 平面图最小割=对偶图最短路 假设起点和终点间有和其他边都不相交的一条虚边. 如图,平面图的若干条边将一个平面划分为若干个图形,每个图形就是对偶图中的一个 ...

  5. BZOJ2007 [Noi2010]海拔 【平面图最小割转对偶图最短路】

    题目链接 BZOJ2007 题解 这是裸题啊,,要是考试真的遇到就好了 明显是最小割,而且是有来回两个方向 那么原图所有向右的边转为对偶图向下的边 向左的边转为向上 向下转为向左 向上转为向右 然后跑 ...

  6. bzoj1001/luogu4001 狼抓兔子 (最小割/平面图最小割转对偶图最短路)

    平面图转对偶图:先在原图中加一个s->t的边,然后对每个面建一个点,对每条分隔两个面的边加一条连接这两个面对应点的边,边权等于原边权. 然后从刚才加的s->t分割出来的两面对应的两个点跑最 ...

  7. 【Bzoj】1001狼抓兔子(平面图最小割转对偶图最短路)

    YEAH 题目链接 终于做对这道题啦    建图的艰辛难以言表- - 顺便说一句我队列转STL啦 狼抓兔子的地图符合平面图定义,于是将该图转成对偶图并求出对偶图的最短路即可. 这篇博客给了我极大的帮助 ...

  8. bzoj1001平面图最小割转对偶图最短路

    https://www.lydsy.com/JudgeOnline/problem.php?id=1001 很明显的求对偶图的最短路即可(由于特判写错了一直wa = = ) //#pragma com ...

  9. B20J_2007_[Noi2010]海拔_平面图最小割转对偶图+堆优化Dij

    B20J_2007_[Noi2010]海拔_平面图最小割转对偶图+堆优化Dij 题意:城市被东西向和南北向的主干道划分为n×n个区域.城市中包括(n+1)×(n+1)个交叉路口和2n×(n+1)条双向 ...

随机推荐

  1. WPF中Popup控件在Win7以及Win10等中的对齐点方式不一样的解决方案 - 简书

    原文:WPF中Popup控件在Win7以及Win10等中的对齐点方式不一样的解决方案 - 简书 最近项目中使用弹出控件Popup,发现弹出框的对齐方式在不同的系统中存在不同(Popup在win10上是 ...

  2. yaml中的锚点和引用

    项目引入yaml语言来写配置文件,最近发现利用其锚点&和引用*的功能,可以极大减少配置文件中的重复内容,将相同配置内容收敛到锚点处,修改时,只需要修改锚点处的内容,即可在所有引用处生效. ya ...

  3. 【Unity3d】MenuItem修饰的方法无法触发的可能原因

    遇到了MenuItem修饰的方法无法触发的情况,顺利解决. 类放在Editor目录下,该类下其他方法被MenuItem修饰可以触发. 后来发现我修饰的方法和该类下另一个方法重名了. 改方法名,问题解决 ...

  4. 现有新的iOS更新可用,请从iOS12 beta版进行更新.解决方案

    问题描述: ios系统一直弹出“现有新的iOS更新可用,请从iOS12 beta版进行更新”的提示,很烦的. 应该只出现在安装测试版ios12的手机上. 解决方案: 删除描述文件无法解决. 有网友机制 ...

  5. axios封装(二)队列管理

    在某些特定的场景(比如 即时搜索 ,表格分页),会频繁的发起ajax请求,而由于ajax是异步API,所以返回的时序并不能够保证,这时候就需要实现一个ajax队列,在相同的请求发起时,取消处理上一个请 ...

  6. 设计模式C++实现

    准备写一系列笔记用来记录学习设计模式的过程,同时写出自己对几种主要的设计模式的理解,以及编码实现,同时总结. 主要参考书籍就是 <Head First Design Patterns>这本 ...

  7. Mysql 单表主从同步

    先配主从同步,后将主库表老数据传输到从库 说明:api-server的数据库为主,其他harbor为从 1.master 配置文件更改 [mysqld] log-bin = mysql-bin ser ...

  8. java引用Arcface,实现人脸识别(demo)

    ## 开发环境准备: ###开发使用到的软件和工具: * Jdk8.mysql5.7.libarcsoft_face.dll(so).libarcsoft_face_engine.dll(so).li ...

  9. Machine Learning笔记整理 ------ (一)基本概念

    机器学习的定义:假设用P来评估计算机程序在某任务类T上的性能,若一个程序通过利用经验E,使其在T中任务获得了性能改善,我们则说关于任务类T和P,该程序对经验E进行了学习(Mitchell, 1997) ...

  10. css 元素水平垂直方向居中

    html部分 <div class="parent"> <div class="child"> - -居中- - </div> ...