传送门:【HDU】4859

题目分析:

最小割的思想真是博大精深!

本题的模型是最小割。

我们需要最大化海岸线的长度,如果相邻两点属性不同才会存在海岸线(海和陆地),所以我们可以将题目转化成最小化不是海岸线的条数。

首先在地图的外围围上一圈‘D’,然后将整个图黑白染色(点的奇偶性),之后我们对所有相邻的点建边<u,v>,<v,u>,表示u能到v,v能到u。然后,我们对所有为'.'且在白色格子的或者为'D'且在黑色格子的点和源点(汇点)建边,对所有为'D'且在白色格子的或者为'.'且在黑色格子的点和汇点(源点)建边。

这样从源点到汇点则只能通过'.'->'.'或者'D'->'D'这样的边从源点流向汇点。

这样我们跑一遍最大流就知道了相邻点属性相同的边的最少条数(最小割)。

那么图中的'E'我们要不要管呢?我们可以设想,如果有流量通过E从源点到汇点,那么相当于将'E'定属性(海或陆地),这里最大流的意义就是:将'E'定属性以后尽量最大化相邻点属性相同的边的条数。通过流决定'E'的属性。

等等?刚才我们好像说是最大化?其实并没有错,就是最大化,这是最大流的属性,但是最大流与最小割是一个对偶问题,我们得到的最大流其实就是最小割,也就是说我们最大化后的结果其实就是要求的最少的不是海岸线的条数。是不是很神奇?

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define REV( i , n ) for ( int i = n - 1 ; i >= 0 ; -- i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define FOV( i , a , b ) for ( int i = a ; i >= b ; -- i )
#define REPF( i , a , b ) for ( int i = a ; i < b ; ++ i )
#define REPV( i , a , b ) for ( int i = a - 1 ; i >= b ; -- i )#define CLR( a , x ) memset ( a , x , sizeof a )
#define CPY( a , x ) memcpy ( a , x , sizeof a )const int MAXG = 50 ;
const int MAXN = 2505 ;
const int MAXE = 1000000 ;
const int MAXQ = 1000000 ;
const int INF = 0x3f3f3f3f ;struct Edge {int v , c , n ;Edge () {}Edge ( int v , int c , int n ) : v ( v ) , c ( c ) , n ( n ) {}
} ;struct NetWork {Edge E[MAXE] ;int H[MAXN] , cntE ;int d[MAXN] , cur[MAXN] , pre[MAXN] , num[MAXN] ;int Q[MAXQ] , head , tail ;int s , t , nv ;int flow ;int n , m ;char G[MAXG][MAXG] ;void init () {cntE = 0 ;CLR ( H , -1 ) ;}void addedge ( int u , int v , int c , int rc = 0 ) {E[cntE] = Edge ( v ,  c , H[u] ) ;H[u] = cntE ++ ;E[cntE] = Edge ( u , rc , H[v] ) ;H[v] = cntE ++ ;}void rev_bfs () {CLR ( num , 0 ) ;CLR ( d , -1 ) ;head = tail = 0 ;Q[tail ++] = t ;d[t] = 0 ;num[d[t]] = 1 ;while ( head != tail ) {int u = Q[head ++] ;for ( int i = H[u] ; ~i ; i = E[i].n ) {int v = E[i].v ;if ( ~d[v] )continue ;d[v] = d[u] + 1 ;num[d[v]] ++ ;Q[tail ++] = v ;}}}int ISAP () {CPY ( cur , H ) ;rev_bfs () ;flow = 0 ;int u = pre[s] = s , i ;while ( d[s] < nv ) {if ( u == t ) {int f = INF , pos ;for ( i = s ; i != t ; i = E[cur[i]].v )if ( f > E[cur[i]].c ) {f = E[cur[i]].c ;pos = i ;}for ( i = s ; i != t ; i = E[cur[i]].v ) {E[cur[i]].c -= f ;E[cur[i] ^ 1].c += f ;}flow += f ;u = pos ;}for ( i = cur[u] ; ~i ; i = E[i].n )if ( E[i].c && d[u] == d[E[i].v] + 1 )break ;if ( ~i ) {cur[u] = i ;pre[E[i].v] = u ;u = E[i].v ;}else {if ( 0 == ( -- num[d[u]] ) )break ;int mmin = nv ;for ( i = H[u] ; ~i ; i = E[i].n )if ( E[i].c && mmin > d[E[i].v] ) {cur[u] = i ;mmin = d[E[i].v] ;}d[u] = mmin + 1 ;num[d[u]] ++ ;u = pre[u] ;}}return flow ;}void input () {CLR ( G , 'D' ) ;scanf ( "%d%d" , &n , &m ) ;FOR ( i , 1 , n )scanf ( "%s" , G[i] + 1 ) , G[i][m + 1] = 'D' ;n += 2 , m += 2 ;s = n * m ;t = s + 1 ;nv = t + 1 ;REP ( i , n )REP ( j , m ) {if ( ( i + j ) % 2 && G[i][j] == '.' || ( i + j ) % 2 == 0 && G[i][j] == 'D' )addedge ( s , i * m + j , INF ) ;if ( ( i + j ) % 2 && G[i][j] == 'D' || ( i + j ) % 2 == 0 && G[i][j] == '.' )addedge ( i * m + j , t , INF ) ;if ( i < n - 1 )addedge ( i * m + j , ( i + 1 ) * m + j , 1 , 1 ) ;if ( j < m - 1 )addedge ( i * m + j , i * m + ( j + 1 ) , 1 , 1 ) ;}}void solve () {init () ;input () ;printf ( "%d\n" , ( n - 1 ) * m + n * ( m - 1 ) - ISAP () ) ;}
} z ;int main () {int T , cas = 0 ;scanf ( "%d" , &T ) ;while ( T -- ) {printf ( "Case %d: " , ++ cas ) ;z.solve () ;}return 0 ;
}

【HDU】4859 海岸线 黑白染色+最小割相关推荐

  1. 牛客contest897 D-Bamboo Rat(二分+黑白染色+最小割)

    题目链接 题意 N×MN×MN×M的矩阵选择KKK个数相邻的数字不能同时选择,让最小的数字最大. 思路 二分枚举答案,对于每个答案,DinicDinicDinic判断可行性. #include < ...

  2. HDU 4859 海岸线 最小割

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

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

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

  4. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  5. HDU 4859-海岸线(网络流_最小割)

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

  6. hdu 5285 二分图黑白染色

    题意:给出 n 个人,以及 m 对互不认识的关系,剩余的人都互相认识,要将所有人分成两组,组内不能有互不认识的人,要求每组至少有一人,并且第一组人数尽量多,问两组人数或不可能时单独输出 BC 48 场 ...

  7. hdu 6852Path6(最短路+最小割)

    传送门 •题意 有n个城市,标号1-n 现花费最小的代价堵路 使得从1号城市到n号城市的路径边长 (注意只是变长不是最长) 堵一条路的代价是这条路的权值 •思路 在堵路以前,从1到n的最小路径当然是最 ...

  8. HDU - 6214 Smallest Minimum Cut(最小割最少边数)

    题目链接:点击查看 题目大意:给出一张由n个点以及m条边组成的有向图,现在要求出最少割掉几条边使得整张图不连通并且割掉边的权值最小 题目分析:题目的意思也就是要求最小割的最少边数,这里有两个方法: 先 ...

  9. HDU - 5889 Barricade(最短路+最小割-最大流)

    题目链接:点击查看 题目大意:给出一张无向图,每条边的长度为1,第i条边建立障碍的花费为wi,题目要求在保证从1到n号点的所有的最短路径上,都有障碍的情况下的最小费用 题目分析:要求最短路上的最小割, ...

最新文章

  1. 【SVN】svn“E155017工作副本的参考文件损坏、E200014文件校验和不匹配”的解决方法
  2. More than React(一)为什么ReactJS不适合复杂交互的前端项目?
  3. python小程序源代码-Python小项目:开发一个动态时钟小程序(附源码)
  4. NumberOf1Bits(leetcode191)
  5. struts2操作json成字符串格式错误被转义及其前台访问json对象的方法
  6. Java里的堆(heap)栈(stack)和方法区(method)
  7. Boost.MultiIndex 使用序列索引的示例
  8. 资深开发者们是如何读书的?---线下读书会记录
  9. android 7.0 解锁亮屏,Android7.0亮屏流程分析
  10. 通过Nacos让Nginx拥有服务发现能力
  11. 2011年8月5日星期五
  12. web性能优化--缓存
  13. wordpress博客加载缓慢解决:去除Open Sans和Lato 字体
  14. 移动支付“车水码龙”,但也小心“塞翁失码”
  15. 池化层(汇聚层)的通道变化
  16. mybatis在工作中的使用简介
  17. 【GraphVisual】画节点与线以及移动节点线随着移动
  18. elment-ui的el-select选择器blur事件失效 bug解决
  19. MT6701磁编码器使用指南,14Bit单圈绝对值,I2C stm32 HAL库读角度,兼容AS5600
  20. redis文件事件和时间事件

热门文章

  1. spring+struts2+ibatis整合完全步骤
  2. PTA.1060爱丁顿数
  3. 我的世界服务器钟表菜单怎么制作,论钟表菜单的食用[使用]方法
  4. 店铺有展现没有点击怎么办
  5. 商汤科技通过港交所上市聆讯,三年半累计收入近100亿元
  6. Windows10系统下怎样使用快捷键打开控制面板
  7. 在Windows操作系统中怎样使用nc命令
  8. 用css快速绘制多边形(三角形/菱形/梯形/五角星)-polygon辅助属性
  9. 计算机课实验报告排版,大学计算机排版作业实验报告.doc
  10. 南开02-06经济学考研真题和我的一点考研心得