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

题目大意:

  在一个矩形周围都是海,这个矩形中有陆地,深海和浅海。浅海是可以填成陆地的。

  求最多有多少条方格线满足两侧分别是海洋和陆地

这道题很神

首先考虑一下,什么情况下能够对答案做出贡献

就是相邻的两块不一样的时候

这样我们可以建立最小割模型,可是都说是最小割了

无法求出最大的不相同的东西

所以我们考虑转化,用总的配对数目 - 最小的相同的对数

至于最小的相同的对数怎么算呢?

我们考虑这样的构造方法:

 把整个棋盘黑白染色,我们想要所有的黑格子都是陆地,所有的白格子都是海洋

 但是天不尽人意

 输入数据肯定不会给你做出这种东西,所以会出现各种各样的不符的格子

 所以我们把所有符合的格子和不符的格子拿开

 把所有的与其所在的集合相符的格子放到一个集合中(记为S1)

 把所有的与其所在的集合不相符的格子放到另一个集合中(记为S2)

 把剩下的没有被分到任何集合的格子,也就是所有的E格,放到另一个集合中(记为S3)

 然后我们在所有相邻且所在集合不同(S1,S2,S3)点之间连上双向边

 这时图中存在的任意一条从S -> T的可行流都一定经过S1,S2集合中两个形式相同的格子

 这时候还有可能经过若干S3中的点

 那么这时候就代表我们让这些S3中的点和S1,S2中我们选择的点的形式相同

 这就是最小的相同对数了

 所以ans = tot - dinic()其中tot = (n-1)*m + (m-1)*n

 做完了题了我们定义一下每一条边的含义:

  一条边一定是条双向边

  这条边代表的含义就是这条边连接的两个点必须相同才有可能对答案做出贡献

  而我们知道,一条边连接的两个格子一定在最初的黑白染色中属于不同的颜色

  如果他们颜色相同的话,一定不会被一起分到s1或s2集合中

  并且一定会被分散到S1和S2集合中

  所以我们不能连接相同集合中的边,却能连接不同集合中的边

但是连接的话从数值上来说是不变的,可是本人认为意义上解释不通

网上的其他题解都是没有关心是否在同一个集合内部,都进行了连边

不过本人太弱,无论如何都想不通集合内部的边的意义,所以本人认为那条边不应该存在,是没有意义的。

如果真的是本苣太弱了,还请各位dalao高台贵手。。

Code : 删去了集合内部的边,依然AC

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=*x+ch-'',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
const int maxn = ;
const int maxnode = ;
const int maxedge = ;
const int inf = 0x3f3f3f3f;
struct Edge{
int to,next,cap;
}G[maxedge<<];
int head[maxnode],cnt=;
void add(int u,int v,int c){
G[++cnt].to = v;
G[cnt].next = head[u];
G[cnt].cap = c;
head[u] = cnt;
}
void insert(int u,int v,int c){
add(u,v,c);add(v,u,);
}
int dis[maxnode],q[maxnode],l,r;
int S,T,cur[maxnode];
#define v G[i].to
bool bfs(){
memset(dis,-,sizeof dis);
dis[S] = ;l = ;r = -;
q[++r] = S;
while(l <= r){
int u = q[l++];
for(int i = head[u];i;i=G[i].next){
if(dis[v] == - && G[i].cap){
dis[v] = dis[u] + ;
q[++r] = v;
}
}
}return dis[T] != -;
}
int dfs(int u,int f){
if(u == T || f == ) return f;
int ret = ;
for(int &i = cur[u];i;i=G[i].next){
if(dis[v] == dis[u] + ){
int x = dfs(v,cat_min(G[i].cap,f));
ret += x;f -= x;
G[i].cap -= x;G[i^].cap += x;
if(f == ) break;
}
}if(ret == ) dis[u] = -;
return ret;
}
#undef v
inline int dinic(){
int ret = ;
while(bfs()){
memcpy(cur,head,sizeof head);
ret += dfs(S,inf);
}return ret;
}
int tag[maxnode];
inline void init(){
memset(head,,sizeof head);
memset(tag,,sizeof tag);
cnt = ;S = maxnode - ;T = S+;
}
char map[maxn][maxn],ch;
#define f(x,y) ((x-1)*m+y)
int dx[] = {,,,,-};
int dy[] = {,,-,,};
int main(){
int tim;read(tim);
for(int Case = ;Case <= tim;++Case){
init();
int n,m;read(n);read(m);
for(int i=;i<=n+;++i) map[i][] = map[i][m+] = 'D';
for(int i=;i<=m+;++i) map[][i] = map[n+][i] = 'D';
for(int i=;i<=n+;++i){
for(int j=;j<=m+;++j){
while(ch=getchar(),ch<'!');
map[i][j] = ch;
}
}n += ;m += ;
for(int i=;i<=n;++i){
for(int j=;j<=m;++j){
if((i+j)&){
if(map[i][j] == '.') insert(S,f(i,j),inf),tag[f(i,j)] = ;
if(map[i][j] == 'D') insert(f(i,j),T,inf),tag[f(i,j)] = ;
}else{
if(map[i][j] == 'D') insert(S,f(i,j),inf),tag[f(i,j)] = ;
if(map[i][j] == '.') insert(f(i,j),T,inf),tag[f(i,j)] = ;
}
for(int k=;k<=;++k){
int nx = i + dx[k];
int ny = j + dy[k];
if(nx < || ny < || nx > n || ny > m) continue;
if(tag[f(i,j)] == || tag[f(nx,ny)] == ) insert(f(i,j),f(nx,ny),);
else if(tag[f(i,j)] != tag[f(nx,ny)]) insert(f(i,j),f(nx,ny),);
}
}
}
int ans = (*n*m) - (n+m) - dinic();
printf("Case %d: %d\n",Case,ans);
}
getchar();getchar();
return ;
}

hdu 4859 海岸线 Bestcoder Round 1的更多相关文章

  1. hdu 5636 搜索 BestCoder Round #74 (div.2)

    Shortest Path  Accepts: 40  Submissions: 610  Time Limit: 4000/2000 MS (Java/Others)  Memory Limit: ...

  2. HDU 5904 - LCIS (BestCoder Round #87)

    HDU 5904 - LCIS [ DP ]    BestCoder Round #87 题意: 给定两个序列,求它们的最长公共递增子序列的长度, 并且这个子序列的值是连续的 分析: 状态转移方程式 ...

  3. hdu 4859 海岸线 最小割

    海岸线 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4859 Description 欢迎来到珠海! 由于土地资源越来越紧张,使得许多海滨城市都只能 ...

  4. HDU 4859 海岸线(最小割+最大独立点权变形)

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题意: 欢迎来到珠海!由于土地资源越来越紧张,使得许多海滨城市都只能依靠填海来扩展市区以求发展.作为Z市的 ...

  5. HDU 4859 海岸线(最大流最小割)

    难得的中文题,就不翻译了. 输入第一行为T,表示有T组测试数据.每组数据以两个整数N和M开始,表示地图的规模.接下来的N行,每一行包含一个长度为M的字符串,表示地图,‘.’表示陆地,’E’表示浅海域, ...

  6. HDU 5778 abs (BestCoder Round #85 C)素数筛+暴力

    分析:y是一个无平方因子数的平方,所以可以从sqrt(x)向上向下枚举找到第一个无平方因子比较大小 大家可能觉得这样找过去暴力,但实际上无平方因子的分布式非常密集的,相关题目,可以参考 CDOJ:无平 ...

  7. HDU 5776 sum (BestCoder Round #85 A) 简单前缀判断+水题

    分析:就是判断简单的前缀有没有相同,注意下自身是m的倍数,以及vis[0]=true; #include <cstdio> #include <cstdlib> #includ ...

  8. hdu 5101 Select(Bestcoder Round #17)

    Select                                                    Time Limit: 4000/2000 MS (Java/Others)     ...

  9. HDU 5908 Abelian Period (BestCoder Round #88 模拟+暴力)

    HDU 5908 Abelian Period (BestCoder Round #88 模拟+暴力) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=59 ...

随机推荐

  1. Workflow笔记3——BookMark和持久化

    BookMark 我们在平时的工作流使用中,并不是直接这样一气呵成将整个工作流直接走完的,通常一个流程到了某一个节点,该流程节点的操作人,可能并不会马上去处理该流程,而只有当处理人处理了该流程,流程才 ...

  2. 用Fiddler模拟低速网络环境

    有时候宽频网路用习惯了… 在开发的过程就比较少去考虑最佳化的问题… 但当有人反应说「你的网页好慢」甚至当网路速度慢,会造成你的网页跳出什么啊哩不哒的bug时要如何重现呢? 我们可以用Fiddler 这 ...

  3. solr添加多个core

    在D:\solr\solr_web\solrhome文件夹下: 1)创建core0文件夹 2)复制D:\solr\solr_web\solrhome\configsets\basic_configs/ ...

  4. xcode中的.h和.m文件分别是什么意思?各有什么用?

    .h 表示头文件,用来声明各种成员变量,方法,属性之类的.在import的时候用头文件. .m 主要用来实现.h 里声明的方法.举个例子,如果要写一个方法,你要在.h里先声明: - (void)myM ...

  5. poi读取excel模板,填充内容并导出,支持导出2007支持公式自动计算

    /** * 版权所有(C) 2016 * @author www.xiongge.club * @date 2016-12-7 上午10:03:29 */ package xlsx; /** * @C ...

  6. js条件判断时隐式类型转换

    Javascript 中,数字 0 为假,非0 均为真 在条件判断运算 == 中的转换规则是这样的: 如果比较的两者中有布尔值(Boolean),会把 Boolean 先转换为对应的 Number,即 ...

  7. pagebean pagetag java 后台代码实现分页 demo 前台标签分页 后台java分页

    java 后台代码实现分页 demo 实力 自己写的 标签分页 package com.cszoc.sockstore.util; import java.util.HashMap;import ja ...

  8. Mysql Join

    在前面的博文中,我们已经学会了如果在一张表中读取数据,这是相对简单的,但是在真正的应用中经常需要从多个数据表中读取数据. 本章节我们将向大家介绍如何使用 MySQL 的 JOIN 在两个或多个表中查询 ...

  9. Programming Contest Problem Types

        Programming Contest Problem Types Hal Burch conducted an analysis over spring break of 1999 and ...

  10. hdu1032 Train Problem II (卡特兰数)

    题意: 给你一个数n,表示有n辆火车,编号从1到n,入站,问你有多少种出站的可能.    (题于文末) 知识点: ps:百度百科的卡特兰数讲的不错,注意看其参考的博客. 卡特兰数(Catalan):前 ...