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. Maven对插件进行全局设置

    并不是所有插件都适合从命令行配置,有些参数的值从项目创建到发布都不会改变,或者很少改变,对于这种情况,在POM文件中一次性配置就显然比重复在命令行中输入要方便了. 用户可以在生命插件的时候,对插件进行 ...

  2. 评《撸一段 SQL ? 还是撸一段代码? 》

    最近看到一篇博客<撸一段 SQL ? 还是撸一段代码?>,文章举例说明了一个连表查询使用程序code来写可读性可维护性更好,但是回帖意见不一致,我想作者在理论层面没有做出更好的论述,而我今 ...

  3. 简单的学习心得:网易云课堂Android开发第五章SharedPreferences与文件管理

    一.SharedPreferences (1)SharedPreferences能够用来保存一些属于基本数据类型的数据. (2)保存数据,删除数据都是由SharedPreferences的内部接口Ed ...

  4. iOS 应用程序生命周期

    开发应用程序都要了解其生命周期. 今天我们接触一下iOS应用程序的生命周期, iOS的入口在main.m文件: int main(int argc, char * argv[]) { @autorel ...

  5. iOS xml文件的解析方式 XMLDictionary,GDataXMLNode,NSXMLParser

    iOS9之后,默认网络请求是https,所有我们要设置一下网络安全,具体设置如下 1.第三方类库 XMLDictionary 下载地址: https://github.com/nicklockwood ...

  6. 3Sum algorithm - 非常容易理解的实现 (java)

    原题重述:(点击图片可以进入来源链接) 这到题目的中文解释是, 输入一个数组,例如{-1 0 1 2 -1 -4},从数组中找三个数(a,b,c),使得其和0,输出所有的(a,b,c)组合. 要求ab ...

  7. SQLServer中Partition By 函数的使用

    今天群里看到一个问题,在这里概述下:查询出不同分类下的最新记录.一看这不是很简单的么,要分类那就用Group By;要最新记录就用Order By呗.然后在自己的表中试着做出来: 首先呢我把表中的数据 ...

  8. 6-2 sed 命令

    1. sed : stream editor,流编辑器 是处理纯ASICC纯文本,按行琢行操作的. 编辑器有两种,行编辑器和全屏编辑器 sed:默认不编辑原文件,仅对模式空间中的数据做处理,而后.处理 ...

  9. ubuntu kylin 14.04安装配置redis-2.8.9(转)

    1.下载安装文件加压.编译和安装 cd /tmpwget http://download.redis.io/releases/redis-2.8.9.tar.gztar -zxf redis-2.8. ...

  10. 压缩和解压文件:tar gzip bzip2 compress(转)

    tar[必要参数][选择参数][文件] 压缩:tar -czvf filename.tar.gz targetfile解压:tar -zxvf filename.tar.gz参数说明: -c 建立新的 ...