【hdu 4859】海岸线(图论--网络流最小割)
题意:有一个区域,有'.'的陆地,'D'的深海域,'E'的浅海域。其中浅海域可以填充为陆地。这里的陆地区域不联通,并且整个地图都处在海洋之中。问填充一定浅海域之后所有岛屿的最长的海岸线之和。
解法:最小割。从“分隔”陆地和海域可以想到“割”的概念,然后我们先不考虑浅海域,要深海域和陆地的对数尽量大,也就是相同的地理构造对数尽量小。
于是我们建立一个二分图,深海域和陆地都分列两侧,对于相邻的一个在左,一个在右,也就是“行+列”是奇数的放左,偶数的在右。而对于相邻的深海域和陆地,它们在图中理应分列两侧,才有“相连”的意义。(唉,我算是“梗着脖子”地在解释......~(-仝-)~)于是可以深海域的奇数的在左,而陆地的偶数的在左。
接着建立一个源点和汇点,左侧的点与源点相连,右侧的点与汇点相连。由于无约束,边容量为INF。而4个方向相邻的都“相连”,便建边,容量为1,表示割这条边的代价就是1。又因为这整个地图都处在海洋之中,也就是这个地图外围是一圈深海域,这是隐含条件,所以还需要另外建这些点和对应的边。
最后,用最大流算法求出最小割,表示相同的地理构造的最少的对数,而最长的海岸线就是最多的不同的构造,也就是总对数-最少的相同的地理构造的对数。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<queue> 6 using namespace std; 7 8 const int N=50,NN=3000,MM=30000,INF=20000; 9 int n,m,len=1; 10 int last[NN],d[NN]; 11 int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; 12 char s[N][N]; 13 struct node{int x,y,fl,next;}a[MM]; 14 queue<int> q; 15 16 int mmin(int x,int y) {return x<y?x:y;} 17 void ins(int x,int y,int fl) 18 { 19 a[++len].x=x,a[len].y=y,a[len].fl=fl; 20 a[len].next=last[x],last[x]=len; 21 a[++len].x=y,a[len].y=x,a[len].fl=0; 22 a[len].next=last[y],last[y]=len; 23 } 24 bool bfs(int st,int ed) 25 { 26 while (!q.empty()) q.pop(); 27 memset(d,0,sizeof(d)); 28 q.push(st); d[st]=1; 29 while (!q.empty()) 30 { 31 int x=q.front(); q.pop(); 32 for (int i=last[x];i;i=a[i].next) 33 { 34 int y=a[i].y; 35 if (!a[i].fl||d[y]) continue; 36 d[y]=d[x]+1; q.push(y); 37 } 38 } 39 return d[ed]; 40 } 41 int dfs(int x,int flow,int ed) 42 { 43 if (x==ed) return flow; 44 int sum=0; 45 for (int i=last[x];i;i=a[i].next) 46 { 47 int y=a[i].y; 48 if (d[y]!=d[x]+1||!a[i].fl) continue; 49 int t=dfs(y,mmin(flow-sum,a[i].fl),ed); 50 sum+=t; 51 a[i].fl-=t,a[i^1].fl+=t; 52 if (sum==flow) break; 53 } 54 if (!sum) d[x]=0; 55 return sum; 56 } 57 int Max_flow(int st,int ed) 58 { 59 int sum=0; 60 while (bfs(st,ed)) sum+=dfs(st,INF,ed); 61 return sum; 62 } 63 int ID(int x,int y) {return (x-1)*m+y;} 64 int main() 65 { 66 int T; 67 scanf("%d",&T); 68 for (int kase=1;kase<=T;kase++) 69 { 70 scanf("%d%d",&n,&m); 71 for (int j=1;j<=m+2;j++) s[1][j]='D'; 72 for (int i=2;i<=n+1;i++) 73 { 74 scanf("%s",s[i]+2); 75 s[i][1]=s[i][m+2]='D'; 76 } 77 for (int j=1;j<=m+2;j++) s[n+2][j]='D'; 78 n+=2,m+=2; 79 80 int st=n*m+1,ed=n*m+2; 81 memset(last,0,sizeof(last)); 82 len=1; 83 for (int i=1;i<=n;i++) 84 { 85 for (int j=1;j<=m;j++) 86 { 87 if (i==1||i==n||j==1||j==m) s[i][j]='D'; 88 int t=ID(i,j); 89 if (s[i][j]=='.') 90 { 91 if ((i+j)%2) ins(st,t,INF); 92 else ins(t,ed,INF); 93 } 94 if (s[i][j]=='D') 95 { 96 if ((i+j)%2) ins(t,ed,INF); 97 else ins(st,t,INF); 98 } 99 for (int k=0;k<4;k++) 100 { 101 int x=i+dx[k],y=j+dy[k],tt=ID(x,y); 102 if (x<1||y<1||x>n||y>m) continue; 103 ins(t,tt,1); 104 } 105 } 106 } 107 int ans=Max_flow(st,ed); 108 ans=(n-1)*m+(m-1)*n-ans; 109 printf("Case %d: %d\n",kase,ans); 110 } 111 return 0; 112 }
转载于:https://www.cnblogs.com/konjak/p/6059703.html
【hdu 4859】海岸线(图论--网络流最小割)相关推荐
- 【HDU】4859 海岸线 黑白染色+最小割
传送门:[HDU]4859 题目分析: 最小割的思想真是博大精深! 本题的模型是最小割. 我们需要最大化海岸线的长度,如果相邻两点属性不同才会存在海岸线(海和陆地),所以我们可以将题目转化成最小化不是 ...
- 图论 —— 网络流 —— 最小割 —— 平面图与对偶图
[平面图] 对于一个图 G=(V,E),若其重画后,在平面任意两条边的交点除了图中点外,没有其他交点,那么这个图称为平面图 在平面图中,由边包围并且其中不含顶点的区域称为面 包围面 R 的所有边组成的 ...
- 图论 —— 网络流 —— 最小割 —— 最大权闭合子图
[概述] 给出一个有向图,每一个点都有一个权值,现在要选择一个权值和最大的子图,使得每个点的后继都在子图中,这个子图就称为最大权闭合子图. 如上图,能选的子图有:Ø.{1,2,3,4,5,6}.{3, ...
- 【bzoj2521】[Shoi2010]最小生成树 网络流最小割
题目描述 Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法.另外,他还知道,某一个图可能有多种不同的 ...
- 【bzoj2132】圈地计划 网络流最小割
题目描述 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土地是一块矩形的区域,可以纵横划 ...
- 洛谷 P1646 [国家集训队]happiness 网络流 最小割 Dinic+当前弧优化
题目链接: https://www.luogu.com.cn/problem/P1646 参考博客: https://siyuan.blog.luogu.org/solution-p1646 算法:网 ...
- HDU 4859 海岸线 最小割
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4859 题解: 这题考察的是最小割. 我们可以这样想:海岸线的长短变化都是E引起的,我们通过把'E'变 ...
- hdu 4859 海岸线【最小割---------Dinic】
海岸线 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- HDU 3313 Key Vertex 胡搞(网络流最小割拆点什么的人家才不会呢)
problem大意:给you一个无loop有向graph,求它的key vertex数目.(最近刚过了英语六级,耶,1Y,炫耀~~~~~) 什么是key vertex呢?就是去掉以后从起点到不了终点了 ...
最新文章
- 怎样用计算机命令修复软件,电脑修复指令是什么
- 第二十三期:程序员节Keep被曝突然裁员300多人,60%是开发和运营
- Python中使用Redis的批处理工具pipeline(这种方法从底层思考效率还是低于“订阅发布机制”)
- Python中的线程及用法
- Servlet JSP和Spring MVC初学指南 PDF
- java开发flex_FLEX+Java开发
- 思科无线服务器,【CISCO wlan】思科无线网络_3-基本配置v2.pdf
- Linux下命令积累
- linux 声卡设备文件夹,Linux操作系统声卡驱动的安装与配置
- 中北大学光电考试复习目录
- web前端笔试题——JS
- smartprinter注册版_SmartPrinter免费版
- 目标检测 | 丰富特征导向Refinement Network用于目标检测(附github源码)
- ShardingJDBC使用总结
- web前段网图分类规划
- 怎样调整3dsMax中的样条曲线
- ROS中四元数、欧拉角、旋转矩阵等格式转换
- 全球及中国BTK抑制剂市场发展状况与投资前景建议报告2022-2028年
- 3、Prism的使用二
- plt保存图像、去白边、去坐标轴、去刻度
热门文章
- 数据库设计三范式(3NF)
- 3个你必须知道的面试新趋势, 抓住秋招尾巴拿下offer
- 拼多多332亿美金市值超网易,黄铮离目标又近了一步!
- node.js 事件循环
- 学习Spring(四) -- Spring的继承与依赖
- HttpServletResponse中sendError与setStatus的区别
- ArcEngine10.1二次开发错误: 无法嵌入互操作类型,请改用适用的接口
- Lotus Notes 中导航的键盘快捷方式
- Q129:PBRT-V3,均匀介质的采样(15.2.1章节)
- mysql4语法_4 MySQL 语法技巧