题目链接

想一下能猜出,最优解中海拔只有0和1,且海拔相同的点都在且只在1个连通块中。

这就是个平面图最小割。也可以转必须转对偶图最短路,不然只能T到90分了。。边的方向看着定就行。

不能忽略回去的边,因为最小割的形状可能很奇怪。

  1. //16232kb 456ms
  2. //平面图点数就是(n-1)^2了。但是边数不是4(n-1)^2,是4n(n-1)!。。
  3. #include <queue>
  4. #include <cstdio>
  5. #include <cctype>
  6. #include <cstring>
  7. #include <algorithm>
  8. //#define gc() getchar()
  9. #define MAXIN 300000
  10. #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
  11. #define mp std::make_pair
  12. #define pr std::pair<LL,int>
  13. #define ID(x,y) ((x-1)*nn+y)
  14. typedef long long LL;
  15. const int N=500*500+5,M=4*500*501+5;
  16. int n,nn,Enum,H[N],nxt[M],to[M],len[M];
  17. bool vis[N];
  18. LL dis[N];
  19. std::priority_queue<pr> q;
  20. char IN[MAXIN],*SS=IN,*TT=IN;
  21. inline int read()
  22. {
  23. int now=0;register char c=gc();
  24. for(;!isdigit(c);c=gc());
  25. for(;isdigit(c);now=now*10+c-'0',c=gc());
  26. return now;
  27. }
  28. #define AddEdge(u,v) to[++Enum]=v,nxt[Enum]=H[u],H[u]=Enum,len[Enum]=read()
  29. LL Dijkstra(int S,int T)
  30. {
  31. memset(dis,0x3f,sizeof dis);
  32. dis[S]=0, q.push(mp(0,S));
  33. while(!q.empty())
  34. {
  35. int x=q.top().second; q.pop();
  36. if(vis[x]) continue;
  37. vis[x]=1;
  38. for(int i=H[x]; i; i=nxt[i])
  39. if(dis[to[i]]>dis[x]+len[i])
  40. q.push(mp(-(dis[to[i]]=dis[x]+len[i]),to[i]));
  41. }
  42. return dis[T];
  43. }
  44. int main()
  45. {
  46. n=read()+1, nn=n-1; int S=0, T=nn*nn+1;
  47. for(int j=1; j<n; ++j) AddEdge(S,ID(1,j));//i==1
  48. for(int i=2; i<n; ++i)
  49. for(int j=1; j<n; ++j) AddEdge(ID(i-1,j),ID(i,j));
  50. for(int j=1; j<n; ++j) AddEdge(ID(nn,j),T);//i==n
  51. for(int i=1; i<n; ++i)
  52. {
  53. AddEdge(ID(i,1),T);//j==1
  54. for(int j=2; j<n; ++j) AddEdge(ID(i,j),ID(i,j-1));
  55. AddEdge(S,ID(i,nn));//j==n
  56. }
  57. for(int j=1; j<n; ++j) AddEdge(ID(1,j),S);
  58. for(int i=2; i<n; ++i)
  59. for(int j=1; j<n; ++j) AddEdge(ID(i,j),ID(i-1,j));
  60. for(int j=1; j<n; ++j) AddEdge(T,ID(nn,j));
  61. for(int i=1; i<n; ++i)
  62. {
  63. AddEdge(T,ID(i,1));
  64. for(int j=2; j<n; ++j) AddEdge(ID(i,j-1),ID(i,j));
  65. AddEdge(ID(i,nn),S);
  66. }
  67. printf("%lld\n",Dijkstra(S,T));
  68. return 0;
  69. }

90分(洛谷)网络流:

  1. /*
  2. 还是建反向边吧,虽然会有一条反向边,但是很难对应上去。。
  3. 注意n要加1,即点数是501*501=251001而不是250000。。够坑(也就坑我这种卡的了)。
  4. */
  5. #include <cstdio>
  6. #include <cctype>
  7. #include <algorithm>
  8. #define gc() getchar()
  9. #define MAXIN 300000
  10. //#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
  11. #define ID(x,y) ((x-1)*n+y)
  12. const int N=501*501+5/*>250005!*/,M=N<<3,INF=0x3f3f3f3f;
  13. int n,src,des,Enum,H[N],cur[N],nxt[M],fr[M],to[M],cap[M],lev[N],pre[N],num[N];
  14. char IN[MAXIN],*SS=IN,*TT=IN;
  15. inline int read()
  16. {
  17. int now=0;register char c=gc();
  18. for(;!isdigit(c);c=gc());
  19. for(;isdigit(c);now=now*10+c-'0',c=gc());
  20. return now;
  21. }
  22. inline void AddEdge(int w,int u,int v)
  23. {
  24. to[++Enum]=v, fr[Enum]=u, nxt[Enum]=H[u], H[u]=Enum, cap[Enum]=w;
  25. to[++Enum]=u, fr[Enum]=v, nxt[Enum]=H[v], H[v]=Enum, cap[Enum]=0;
  26. }
  27. bool BFS()
  28. {
  29. static int q[N];
  30. for(int i=src; i<des; ++i) lev[i]=des+1;
  31. int h=0,t=1; q[0]=des, lev[des]=0;
  32. while(h<t)
  33. {
  34. int x=q[h++];
  35. for(int i=H[x]; i; i=nxt[i])
  36. if(lev[to[i]]==des+1 && cap[i^1])
  37. lev[to[i]]=lev[x]+1, q[t++]=to[i];
  38. }
  39. return lev[src]<=des;
  40. }
  41. int Augment()
  42. {
  43. int mn=INF;
  44. for(int i=des; i!=src; i=fr[pre[i]])
  45. mn=std::min(mn,cap[pre[i]]);
  46. for(int i=des; i!=src; i=fr[pre[i]])
  47. cap[pre[i]]-=mn, cap[pre[i]^1]+=mn;
  48. return mn;
  49. }
  50. long long ISAP()
  51. {
  52. if(!BFS()) return 0;
  53. for(int i=src; i<=des; ++i) ++num[lev[i]],cur[i]=H[i];
  54. int x=src; long long res=0;
  55. while(lev[src]<=des)
  56. {
  57. if(x==des) x=src,res+=Augment();
  58. bool can=0;
  59. for(int i=cur[x]; i; i=nxt[i])
  60. if(lev[to[i]]==lev[x]-1 && cap[i])
  61. {
  62. can=1, cur[x]=i, pre[x=to[i]]=i;
  63. break;
  64. }
  65. if(!can)
  66. {
  67. int mn=des;
  68. for(int i=H[x]; i; i=nxt[i])
  69. if(cap[i]) mn=std::min(mn,lev[to[i]]);
  70. if(!--num[lev[x]]) break;
  71. ++num[lev[x]=mn+1], cur[x]=H[x];
  72. if(x!=src) x=fr[pre[x]];
  73. }
  74. }
  75. return res;
  76. }
  77. int main()
  78. {
  79. n=read()+1, Enum=1, src=1, des=n*n;
  80. for(int i=1; i<=n; ++i)
  81. for(int j=1; j<n; ++j) AddEdge(read(),ID(i,j),ID(i,j+1));
  82. for(int i=1; i<n; ++i)
  83. for(int j=1; j<=n; ++j) AddEdge(read(),ID(i,j),ID(i+1,j));
  84. for(int i=1; i<=n; ++i)
  85. for(int j=1; j<n; ++j) AddEdge(read(),ID(i,j+1),ID(i,j));
  86. for(int i=1; i<n; ++i)
  87. for(int j=1; j<=n; ++j) AddEdge(read(),ID(i+1,j),ID(i,j));
  88. printf("%lld\n",ISAP());
  89. return 0;
  90. }

BZOJ.2007.[NOI2010]海拔(最小割 对偶图最短路)的更多相关文章

  1. bzoj 2007 [Noi2010]海拔——最小割转最短路

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2007 一个点的高度一定不是0就是1.答案一定形如一个左上角的连通块全是0的点.一个右下角的连 ...

  2. 【bzoj2007】[Noi2010]海拔 最小割+对偶图+最短路

    题目描述 YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作一个正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1)×(n+1)个交 ...

  3. [NOI2010]海拔——最小割+对偶图

    题目链接 SOLUTION 想一下最优情况下肯定让平路或下坡尽量多,于是不难想到这样构图:包括左上角的一部分全部为\(0\),包括右下角的一部分全部为\(1\),于是现在问题转化为求那个分界线是什么. ...

  4. BZOJ 2007: [Noi2010]海拔

    2007: [Noi2010]海拔 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2410  Solved: 1142[Submit][Status] ...

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

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

  6. bzoj 2007: [Noi2010]海拔【最小割+dijskstra】

    上来就跑3e5的最大流--脑子抽了 很容易看出,每个地方的海拔都是0或1因为再高了没有意义,又,上去下来再上去没有意义,所以最后一定是从s连着一片0,剩下连着t一片1,然后有贡献的就是01交接的那些边 ...

  7. BZOJ 2007 NOI2010 海拔高度 最小减产计划

    标题效果:YT城市是一个精心规划的城市.这个城市是东西向和南北向干道成n×n地区性.简单.可以YT作为一个城市广场,每个区域也可被视为一个正方形.因此,.YT市中含有(n+1)×(n+1)交叉口和2n ...

  8. [NOI2010]海拔(最小割)

    题目描述 YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作一个 正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1)×(n+1)个 ...

  9. [bzoj 1001][Beijing2006]狼抓兔子 (最小割+对偶图+最短路)

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

随机推荐

  1. GraphChi/graphchi-java程序配置

    1.导入graphchi-java maven项目时报错: Plugin execution not covered by lifecycle configuration: org.scala-too ...

  2. 消息队列之RabbitMQ的.Net客户端EasyNetQ

    https://www.cnblogs.com/CoderAyu/p/9072408.html http://www.cnblogs.com/panzi/p/6337568.html http://w ...

  3. (A - 整数划分 HYSBZ - 1263)(数组模拟大数乘法)

    题目链接:https://cn.vjudge.net/problem/HYSBZ-1263 题目大意:中文题目 具体思路:先进了能的拆成3,如果当前剩下的是4,就先不减去3,直接乘4,如果还剩2的话, ...

  4. objective-c 几何类常用方法整理

    CGGeometry参考定义几何结构和功能,操作简单.数据结构中的一个点CGPoint代表在一个二维坐标系统.数据结构的位置和尺寸CGRect代表的一个长方形.数据结构的尺寸CGSize代表宽度和高度 ...

  5. Struts2不扫描jar包中的action

    今天在做一个二开的项目,将struts打成jar包放在WEB-INF的目录下却扫描不到指定的路径,也就是http访问访问不到我们指定的action,其他代码可以正常使用,就是访问不到action.st ...

  6. 用代码截图去理解MVC原理

    [概述] 看了蒋金楠先生的<Asp.Net Mvc框架揭密>,这本书详细地讲解了mvc的原理,很深奥也很复杂,看了几遍才将就明白了一点.他在第一章用了一个他自己写的mvc框架作为例子,代码 ...

  7. elasticsearch安装servicewrapper插件

    1)下载elasticsearch-servicewrappergit clone https://github.com/elasticsearch/elasticsearch-servicewrap ...

  8. C++的那些事 1

    最近在看c++的一些库文件,里面的一些比较陌生但看起来挺有用的一些东西,在此记下,以免日后看到再翻找资料. template <size_t _Nb> 这是在看bitset的时候看到的,之 ...

  9. Linux下创建软Raid

    1- Linux下创建软Raid   步骤1.创建磁盘,并转换为fd #fdisk /dev/sdb //这里使用新的磁盘sdb 然后输入n ,创建分区 使用默认的起始点 输入大小为+100M 然后重 ...

  10. 解决阿里云安骑士漏洞警告:wordpress WPImageEditorImagick 指令注入漏洞

    解决:wordpress WPImageEditorImagick 指令注入漏洞 前些天在阿里云服务器上安装了wordpress,阿里云提示有wordpress WP_Image_Editor_Ima ...