HDU 4859 海岸线 最小割
题目链接:
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 海岸线 最小割相关推荐
- 【HDU】4859海岸线-最小割最大独立点权变形
hdu4859 题解 在矩形外围一圈D,将所有相邻格子连边,海岸线相当于相连的两个格子种类不同的边的数量. 如果是最小化边数就是很经典的最小割模板了,考虑将最大化问题转成最小化相连的两个格子种类相同的 ...
- hdu 4859 海岸线【最小割---------Dinic】
海岸线 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- hdu 4859 海岸线 Bestcoder Round 1
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...
- HDU - 4289 Control(最小割-最大流)
题目链接:点击查看 题目大意:给出一张n个点m条边的无向图,一些恐怖分子要从点st到点ed去安装炸弹,为了阻止他们这样做,必须在某些点布置警察,只要恐怖分子路过警察所在的点就会被逮捕,在某个点布置警察 ...
- HDU 3061 Battle(最小割----最大权闭合图)
题意: Problem Description 由于小白同学近期习武十分刻苦,很快被晋升为天策军的统帅.而他上任的第一天,就面对了一场极其困难的战斗: 据侦查兵回报,前方共有N座城池,考虑到地势原因, ...
- 【HDU】4859 海岸线 黑白染色+最小割
传送门:[HDU]4859 题目分析: 最小割的思想真是博大精深! 本题的模型是最小割. 我们需要最大化海岸线的长度,如果相邻两点属性不同才会存在海岸线(海和陆地),所以我们可以将题目转化成最小化不是 ...
- 【hdu 4859】海岸线(图论--网络流最小割)
题意:有一个区域,有'.'的陆地,'D'的深海域,'E'的浅海域.其中浅海域可以填充为陆地.这里的陆地区域不联通,并且整个地图都处在海洋之中.问填充一定浅海域之后所有岛屿的最长的海岸线之和. 解法:最 ...
- hdu 3046(最小割)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3046 思路:最小割的入门题,设源点为0,汇点为n*m+1,源点与点为2的连一天容量为inf的边,汇点与 ...
- HDU4859 海岸线(最小割)
题目大概就是说一个n*m的地图,地图上每一块是陆地或浅海域或深海域,可以填充若干个浅海域使其变为陆地,问能得到的最长的陆地海岸线是多少. 也是很有意思的一道题. 一开始想歪了,想着,不考虑海岸线重合的 ...
最新文章
- 关于android基础教程一书的初步解读后发现的一些问题
- javaweb网上书店项目设计_计算机毕业设计能不能用成品?
- 哈佛成功金句 -25则
- Encoder-Decoder模型和Attention模型
- 解决自定义actionbar 两边空隙
- oracle数据库数据消失,,保存在数据库里的数据莫名其妙的消失
- WebService传输DataSet压缩与解压缩
- iOS常用第三方类库 Xcode插件
- Docker学习(三)Docker常用命令
- 分享图片至Facebook与Twitter
- 微信防封域名处理 淘客类 检测域名是否被封
- 计算机进制转换练习,二进制十进制八进制十六进制转换练习题.docx
- MYSQL 视图 触发器 存储过程 事务 索引
- ESXi社区版ne1000 VIB驱动的更新
- 0基础能学“软件测试”吗?好学吗?怎么学?
- aardio部署_aardio学习笔记-变量与常量
- K-Stack 2021牛客多校2
- 分享 java 基础 + 进阶精简资料(视频 + 源码 + 就业项目 + 面试报装)
- 新手如何对文件进行简单的上传
- 3 求最大公约数和最小公倍数