hdu 4859 海岸线 Bestcoder Round 1
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的更多相关文章
- hdu 5636 搜索 BestCoder Round #74 (div.2)
Shortest Path Accepts: 40 Submissions: 610 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: ...
- HDU 5904 - LCIS (BestCoder Round #87)
HDU 5904 - LCIS [ DP ] BestCoder Round #87 题意: 给定两个序列,求它们的最长公共递增子序列的长度, 并且这个子序列的值是连续的 分析: 状态转移方程式 ...
- hdu 4859 海岸线 最小割
海岸线 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4859 Description 欢迎来到珠海! 由于土地资源越来越紧张,使得许多海滨城市都只能 ...
- HDU 4859 海岸线(最小割+最大独立点权变形)
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题意: 欢迎来到珠海!由于土地资源越来越紧张,使得许多海滨城市都只能依靠填海来扩展市区以求发展.作为Z市的 ...
- HDU 4859 海岸线(最大流最小割)
难得的中文题,就不翻译了. 输入第一行为T,表示有T组测试数据.每组数据以两个整数N和M开始,表示地图的规模.接下来的N行,每一行包含一个长度为M的字符串,表示地图,‘.’表示陆地,’E’表示浅海域, ...
- HDU 5778 abs (BestCoder Round #85 C)素数筛+暴力
分析:y是一个无平方因子数的平方,所以可以从sqrt(x)向上向下枚举找到第一个无平方因子比较大小 大家可能觉得这样找过去暴力,但实际上无平方因子的分布式非常密集的,相关题目,可以参考 CDOJ:无平 ...
- HDU 5776 sum (BestCoder Round #85 A) 简单前缀判断+水题
分析:就是判断简单的前缀有没有相同,注意下自身是m的倍数,以及vis[0]=true; #include <cstdio> #include <cstdlib> #includ ...
- hdu 5101 Select(Bestcoder Round #17)
Select Time Limit: 4000/2000 MS (Java/Others) ...
- HDU 5908 Abelian Period (BestCoder Round #88 模拟+暴力)
HDU 5908 Abelian Period (BestCoder Round #88 模拟+暴力) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=59 ...
随机推荐
- 响应式手机商城页面顶部样式HTML代码
本特效支持PC浏览器和触屏浏览器. 效果展示 http://hovertree.com/texiao/bootstrap/8/ 手机扫描二维码体验效果: HTML代码如下: <!DOCTYPE ...
- Android Weekly Notes Issue #224
Android Weekly Issue #224 September 25th, 2016 Android Weekly Issue #224 本期内容包括: Google Play的pre-lau ...
- Android开发学习—— Service 服务
Service运行于后台的一个组件,用来运行适合运行在后台的代码,服务是没有前台界面,可以视为没有界面的activity. 服务可以被手动关闭,不会重启,但是如果被自动关闭,内存充足就会重启. sta ...
- 浅谈Android编码规范及命名规范
前言: 目前工作负责两个医疗APP项目的开发,同时使用LeanCloud进行云端配合开发,完全单挑. 现大框架已经完成,正在进行细节模块上的开发 抽空总结一下Android项目的开发规范:1.编码规范 ...
- Hibernate 系列 04 - Hibernate 配置相关的类
引导目录: Hibernate 系列教程 目录 前言: 通过上一篇的增删改查小练习之后,咱们大概已经掌握了Hibernate的基本用法. 我们发现,在调用Hibernate API的过程中,虽然Hib ...
- Git命令
1. 检出项目到本地 git clone git@github.com:michaelliao/gitskills.git 2. 查看当前工作区状态 git status 3. 添加文件或文件夹至版本 ...
- Python写各大聊天系统的屏蔽脏话功能原理
Python写各大聊天系统的屏蔽脏话功能原理 突然想到一个视频里面弹幕被和谐的一满屏的*号觉得很有趣,然后就想用python来试试写写看,结果还真玩出了点效果,思路是首先你得有一个脏话存放的仓库好到时 ...
- 数据库Sharding系列文章
关于数据库Sharding的策略,有人整理出相关的方案,看完收获很大. 数据库分库分表(sharding)系列(五) 一种支持自由规划无须数据迁移和修改路由代码的Sharding扩容方案 数据库分库分 ...
- 【码在江湖】前端少侠的json故事(上)日月第一击
日月第一击 这是我前端生涯第一次和后台对接,其经历真是苦不堪言,多次绝处逢生,柳暗花明,可就是迟迟见不到那条村子.当然,最后我还是完成了这次对接.下面来聊一聊我这白痴一般的经历. 序章 话说天下大势, ...
- [收藏] javascript keycode大全
做了一段的小练习,没往上发了~ 继续补下js的基础知识 ------------------------------------------------------------------------ ...