题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4859

题解:

这题考察的是最小割。

我们可以这样想:海岸线的长短变化都是E引起的,我们通过把’E'变成'.'或'D'来使海岸线最大化。

我们要算海岸线就是算格子‘.'和格子'D'(在原有地图周围四面都要加’D‘)相邻的面数,要使它最大,就是要使'.'与’.';'D'与'D'相邻的面数最小,而面数最小可以用最小割来做。

现在我们先把格子上的点黑白染色,(i+j)%2==1的为A类,为0的为B类,

在A类中,所的’.'与源点相连(容量为INF),所有的’D'与汇点相连(容量为INF)。

在B类中,所有的‘.'与汇点相连(容量为INF),所有的'D'与源点相连(容量为INF)。

E不与源点,汇点相连。

所有的点与周围的四个点连一条有向边(容量为1)。

图建好啦,跑一下最大流,ans=总的面-最大流。

现在让我们来研究一下这图的一些性质:

首先,只有’.'到‘.‘,’D'到'D‘的路径能联通源点汇点

其次,考虑'E'。

如果与‘E’相连的四个点都是'.'或都是'D‘,那这个’E‘,不可能有流通过,也就是它最终的属性肯定与周围的是相反的!

其次如果与‘E'相邻的有’.'和‘D'(这里的'.'和’D'要么都属于A类,要么都属于B类),那么就可能会有不同的流通过(这就是在给E定属性了)。

我们通过最大流算法求出图的最小割,也就是两边相同的面数的最小值。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;const int maxn = 55;
const int INF=0x3f3f3f3f;struct Edge {int from, to, cap, flow;Edge(int from,int to,int cap,int flow):from(from),to(to),cap(cap),flow(flow){}
};struct Dinic {int n, m, s, t;vector<Edge> edges;vector<int> G[maxn*maxn];bool vis[maxn*maxn];int d[maxn*maxn];int cur[maxn*maxn];void init(int n) {this->n = n;for (int i = 0; i < n; i++) G[i].clear();edges.clear();}void addEdge(int from, int to, int cap) {edges.push_back(Edge(from, to, cap, 0));edges.push_back(Edge(to, from, 0, 0));m = edges.size();G[from].push_back(m - 2);G[to].push_back(m - 1);}bool BFS() {memset(vis, 0, sizeof(vis));queue<int> Q;Q.push(s);d[s] = 0;vis[s] = 1;while (!Q.empty()) {int x = Q.front(); Q.pop();for (int i = 0; i < G[x].size(); i++) {Edge& e = edges[G[x][i]];if (!vis[e.to] && e.cap>e.flow) {vis[e.to] = 1;d[e.to] = d[x] + 1;Q.push(e.to);}}}return vis[t];}int DFS(int x, int a) {if (x == t || a == 0) return a;int flow = 0, f;for (int& i = cur[x]; i < G[x].size(); i++) {Edge& e = edges[G[x][i]];if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow)))>0) {e.flow += f;edges[G[x][i] ^ 1].flow -= f;flow += f;a -= f;if (a == 0) break;}}return flow;}int Maxflow(int s, int t) {this->s = s; this->t = t;int flow = 0;while (BFS()) {memset(cur, 0, sizeof(cur));flow += DFS(s, INF);}return flow;}
}dinic;char str[maxn][maxn];
int mp[maxn][maxn];
int n, m,tot;
const int dx[] = { -1,1,0,0 };
const int dy[] = { 0,0,-1,1 };void init() {tot = 1;
}int main() {int tc,kase=0;scanf("%d", &tc);while (tc--) {scanf("%d%d", &n,&m);init();for (int i = 1; i <= n; i++) {scanf("%s", str[i]+1);}n++, m++;for (int i = 0; i <= n; i++) str[i][0] = str[i][m] = 'D';for (int j = 0; j <= m; j++) str[0][j] = str[n][j] = 'D';for (int i = 0; i <= n; i++) {for (int j = 0; j <= m; j++) {mp[i][j] = tot++;}}dinic.init(tot+1);for (int i = 0; i <= n; i++) {for (int j = 0; j <= m; j++) {for (int k = 0; k < 4; k++) {int x = i + dx[k], y = j + dy[k];if (x < 0 || x > n || y < 0 || y > m) continue;dinic.addEdge(mp[i][j], mp[x][y],1);}if ((i + j) % 2) {if (str[i][j] == '.') {dinic.addEdge(mp[i][j], tot, INF);}else if (str[i][j] == 'D') {dinic.addEdge(0, mp[i][j], INF);}}else {if (str[i][j] == '.') {dinic.addEdge(0, mp[i][j], INF);}else if(str[i][j]=='D') {dinic.addEdge(mp[i][j], tot, INF);}}}}int tmp = dinic.Maxflow(0, tot);int ans = (n+1)*(m+1)*2-(m+1)-(n+1)-tmp;printf("Case %d: %d\n",++kase, ans);}return 0;
}

转载于:https://www.cnblogs.com/fenice/p/5557942.html

HDU 4859 海岸线 最小割相关推荐

  1. 【HDU】4859海岸线-最小割最大独立点权变形

    hdu4859 题解 在矩形外围一圈D,将所有相邻格子连边,海岸线相当于相连的两个格子种类不同的边的数量. 如果是最小化边数就是很经典的最小割模板了,考虑将最大化问题转成最小化相连的两个格子种类相同的 ...

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

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

  3. hdu 4859 海岸线 Bestcoder Round 1

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

  4. HDU - 4289 Control(最小割-最大流)

    题目链接:点击查看 题目大意:给出一张n个点m条边的无向图,一些恐怖分子要从点st到点ed去安装炸弹,为了阻止他们这样做,必须在某些点布置警察,只要恐怖分子路过警察所在的点就会被逮捕,在某个点布置警察 ...

  5. HDU 3061 Battle(最小割----最大权闭合图)

    题意: Problem Description 由于小白同学近期习武十分刻苦,很快被晋升为天策军的统帅.而他上任的第一天,就面对了一场极其困难的战斗: 据侦查兵回报,前方共有N座城池,考虑到地势原因, ...

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

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

  7. 【hdu 4859】海岸线(图论--网络流最小割)

    题意:有一个区域,有'.'的陆地,'D'的深海域,'E'的浅海域.其中浅海域可以填充为陆地.这里的陆地区域不联通,并且整个地图都处在海洋之中.问填充一定浅海域之后所有岛屿的最长的海岸线之和. 解法:最 ...

  8. hdu 3046(最小割)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3046 思路:最小割的入门题,设源点为0,汇点为n*m+1,源点与点为2的连一天容量为inf的边,汇点与 ...

  9. HDU4859 海岸线(最小割)

    题目大概就是说一个n*m的地图,地图上每一块是陆地或浅海域或深海域,可以填充若干个浅海域使其变为陆地,问能得到的最长的陆地海岸线是多少. 也是很有意思的一道题. 一开始想歪了,想着,不考虑海岸线重合的 ...

最新文章

  1. 关于android基础教程一书的初步解读后发现的一些问题
  2. javaweb网上书店项目设计_计算机毕业设计能不能用成品?
  3. 哈佛成功金句 -25则
  4. Encoder-Decoder模型和Attention模型
  5. 解决自定义actionbar 两边空隙
  6. oracle数据库数据消失,,保存在数据库里的数据莫名其妙的消失
  7. WebService传输DataSet压缩与解压缩
  8. iOS常用第三方类库 Xcode插件
  9. Docker学习(三)Docker常用命令
  10. 分享图片至Facebook与Twitter
  11. 微信防封域名处理 淘客类 检测域名是否被封
  12. 计算机进制转换练习,二进制十进制八进制十六进制转换练习题.docx
  13. MYSQL 视图 触发器 存储过程 事务 索引
  14. ESXi社区版ne1000 VIB驱动的更新
  15. 0基础能学“软件测试”吗?好学吗?怎么学?
  16. aardio部署_aardio学习笔记-变量与常量
  17. K-Stack 2021牛客多校2
  18. 分享 java 基础 + 进阶精简资料(视频 + 源码 + 就业项目 + 面试报装)
  19. 新手如何对文件进行简单的上传
  20. 3 求最大公约数和最小公倍数

热门文章

  1. python等待一个图片出现
  2. 蓝桥杯——Java中的全排列算法
  3. 用Scrapy对豆瓣top250进行电影详细信息爬取
  4. Wi-Fi P2P overview(一)
  5. Foms验证基于角色(英文)
  6. 关于echarts的雷达图比较详细的参数说明
  7. CSS实现赛博朋克风格按钮
  8. 关于工作时间分配(二)
  9. 单硬盘MBR分区双系统引导解决方法
  10. 现代Java开发速度很快