题意:有一个区域,有'.'的陆地,'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】海岸线(图论--网络流最小割)相关推荐

  1. 【HDU】4859 海岸线 黑白染色+最小割

    传送门:[HDU]4859 题目分析: 最小割的思想真是博大精深! 本题的模型是最小割. 我们需要最大化海岸线的长度,如果相邻两点属性不同才会存在海岸线(海和陆地),所以我们可以将题目转化成最小化不是 ...

  2. 图论 —— 网络流 —— 最小割 —— 平面图与对偶图

    [平面图] 对于一个图 G=(V,E),若其重画后,在平面任意两条边的交点除了图中点外,没有其他交点,那么这个图称为平面图 在平面图中,由边包围并且其中不含顶点的区域称为面 包围面 R 的所有边组成的 ...

  3. 图论 —— 网络流 —— 最小割 —— 最大权闭合子图

    [概述] 给出一个有向图,每一个点都有一个权值,现在要选择一个权值和最大的子图,使得每个点的后继都在子图中,这个子图就称为最大权闭合子图. 如上图,能选的子图有:Ø.{1,2,3,4,5,6}.{3, ...

  4. 【bzoj2521】[Shoi2010]最小生成树 网络流最小割

    题目描述 Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法.另外,他还知道,某一个图可能有多种不同的 ...

  5. 【bzoj2132】圈地计划 网络流最小割

    题目描述 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土地是一块矩形的区域,可以纵横划 ...

  6. 洛谷 P1646 [国家集训队]happiness 网络流 最小割 Dinic+当前弧优化

    题目链接: https://www.luogu.com.cn/problem/P1646 参考博客: https://siyuan.blog.luogu.org/solution-p1646 算法:网 ...

  7. HDU 4859 海岸线 最小割

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4859 题解: 这题考察的是最小割. 我们可以这样想:海岸线的长短变化都是E引起的,我们通过把'E'变 ...

  8. hdu 4859 海岸线【最小割---------Dinic】

    海岸线 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  9. HDU 3313 Key Vertex 胡搞(网络流最小割拆点什么的人家才不会呢)

    problem大意:给you一个无loop有向graph,求它的key vertex数目.(最近刚过了英语六级,耶,1Y,炫耀~~~~~) 什么是key vertex呢?就是去掉以后从起点到不了终点了 ...

最新文章

  1. 怎样用计算机命令修复软件,电脑修复指令是什么
  2. 第二十三期:程序员节Keep被曝突然裁员300多人,60%是开发和运营
  3. Python中使用Redis的批处理工具pipeline(这种方法从底层思考效率还是低于“订阅发布机制”)
  4. Python中的线程及用法
  5. Servlet JSP和Spring MVC初学指南 PDF
  6. java开发flex_FLEX+Java开发
  7. 思科无线服务器,【CISCO wlan】思科无线网络_3-基本配置v2.pdf
  8. Linux下命令积累
  9. linux 声卡设备文件夹,Linux操作系统声卡驱动的安装与配置
  10. 中北大学光电考试复习目录
  11. web前端笔试题——JS
  12. smartprinter注册版_SmartPrinter免费版
  13. 目标检测 | 丰富特征导向Refinement Network用于目标检测(附github源码)
  14. ShardingJDBC使用总结
  15. web前段网图分类规划
  16. 怎样调整3dsMax中的样条曲线
  17. ROS中四元数、欧拉角、旋转矩阵等格式转换
  18. 全球及中国BTK抑制剂市场发展状况与投资前景建议报告2022-2028年
  19. 3、Prism的使用二
  20. plt保存图像、去白边、去坐标轴、去刻度

热门文章

  1. 数据库设计三范式(3NF)
  2. 3个你必须知道的面试新趋势, 抓住秋招尾巴拿下offer
  3. 拼多多332亿美金市值超网易,黄铮离目标又近了一步!
  4. node.js 事件循环
  5. 学习Spring(四) -- Spring的继承与依赖
  6. HttpServletResponse中sendError与setStatus的区别
  7. ArcEngine10.1二次开发错误: 无法嵌入互操作类型,请改用适用的接口
  8. Lotus Notes 中导航的键盘快捷方式
  9. Q129:PBRT-V3,均匀介质的采样(15.2.1章节)
  10. mysql4语法_4 MySQL 语法技巧