题目大概就是说一个n*m的地图,地图上每一块是陆地或浅海域或深海域,可以填充若干个浅海域使其变为陆地,问能得到的最长的陆地海岸线是多少。

也是很有意思的一道题。

一开始想歪了,想着,不考虑海岸线重合的情况那海岸线长度就是所有非深海域的个数*4,而每一块要嘛是陆地要嘛不是陆地,如果浅海域不变成陆地那么花费4,而对于重合情况花费是2,那样似乎是经典的二者选其一的最小割模型,最后的答案就是所有非深海域的个数*4-最小割

不过,那个经典的模型是二者选法不同有额外花费,而这儿是二者同时是陆地有额外花费,这个额外花费指的是重合花费2——入手点也是这儿——

  • 对地图黑白染色,两色的点分别作X部Y部,X部向其相邻的Y部点连容量2的边!
  • 源点向X部是陆地的点连容量INF的边,是浅海域的点连容量4的边,是深海域的点连容量0的边
  • Y部是陆地的点向汇点连容量INF的边,是浅海域的点连容量4的边,是深海域的点连容量0的边

如此建容量网络计算最小割就是要求的最少的花费了,画画图就知道了。

 #include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 2555
#define MAXM 2555*2555 struct Edge{
int v,cap,flow,next;
}edge[MAXM];
int vs,vt,NE,NV;
int head[MAXN]; void addEdge(int u,int v,int cap){
edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].v=u; edge[NE].cap=; edge[NE].flow=;
edge[NE].next=head[v]; head[v]=NE++;
} int level[MAXN];
int gap[MAXN];
void bfs(){
memset(level,-,sizeof(level));
memset(gap,,sizeof(gap));
level[vt]=;
gap[level[vt]]++;
queue<int> que;
que.push(vt);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(level[v]!=-) continue;
level[v]=level[u]+;
gap[level[v]]++;
que.push(v);
}
}
} int pre[MAXN];
int cur[MAXN];
int ISAP(){
bfs();
memset(pre,-,sizeof(pre));
memcpy(cur,head,sizeof(head));
int u=pre[vs]=vs,flow=,aug=INF;
gap[]=NV;
while(level[vs]<NV){
bool flag=false;
for(int &i=cur[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[u]==level[v]+){
flag=true;
pre[v]=u;
u=v;
//aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
aug=min(aug,edge[i].cap-edge[i].flow);
if(v==vt){
flow+=aug;
for(u=pre[v]; v!=vs; v=u,u=pre[u]){
edge[cur[u]].flow+=aug;
edge[cur[u]^].flow-=aug;
}
//aug=-1;
aug=INF;
}
break;
}
}
if(flag) continue;
int minlevel=NV;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==) break;
level[u]=minlevel+;
gap[level[u]]++;
u=pre[u];
}
return flow;
}
int dx[]={,};
int dy[]={,};
int main(){
char map[][];
int t,n,m;
scanf("%d",&t);
for(int cse=; cse<=t; ++cse){
scanf("%d%d",&n,&m);
int tot=;
for(int i=; i<n; ++i){
for(int j=; j<m; ++j){
scanf(" %c",&map[i][j]);
if(map[i][j]!='D') ++tot;
}
}
tot<<=;
vs=n*m; vt=vs+; NV=vt+; NE=;
memset(head,-,sizeof(head));
for(int i=; i<n; ++i){
for(int j=; j<m; ++j){
if(i+j&){
if(map[i][j]=='.') addEdge(vs,i*m+j,INF);
else if(map[i][j]=='E') addEdge(vs,i*m+j,);
for(int k=; k<; ++k){
int nx=i+dx[k],ny=j+dy[k];
if(nx< || nx>=n || ny< || ny>=m) continue;
addEdge(i*m+j,nx*m+ny,);
}
}else{
if(map[i][j]=='.') addEdge(i*m+j,vt,INF);
else if(map[i][j]=='E') addEdge(i*m+j,vt,);
for(int k=; k<; ++k){
int nx=i+dx[k],ny=j+dy[k];
if(nx< || nx>=n || ny< || ny>=m) continue;
addEdge(nx*m+ny,i*m+j,);
}
}
}
}
printf("Case %d: %d\n",cse,tot-ISAP());
}
return ;
}

HDU4859 海岸线(最小割)的更多相关文章

  1. hdu 4859 海岸线 最小割

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

  2. 【HDU4859】 海岸线(网络流-最小割)

    Problem Description 欢迎来到珠海! 由于土地资源越来越紧张,使得许多海滨城市都只能依靠填海来扩展市区以求发展.作为Z市的决策人,在仔细观察了Z市地图之后,你准备通过填充某些海域来扩 ...

  3. HDU 4859(Bestcoder #1 1003)海岸线(网络流之最小割)

    题目地址:HDU4859 做了做杭电多校,知识点会的太少了.还是将重点放在刷专题补知识点上吧,明年的多校才是重点. 这题题目求的最长周长.能够试想一下,这里的海岸线一定是在"."和 ...

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

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

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

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

  6. BZOJ 1391: [Ceoi2008]order [最小割]

    1391: [Ceoi2008]order Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1509  Solved: 460[Submit][Statu ...

  7. BZOJ-2127-happiness(最小割)

    2127: happiness(题解) Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1806  Solved: 875 Description 高一 ...

  8. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  9. BZOJ3438 小M的作物(最小割)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=3438 Description 小M在MC里开辟了两块巨大的耕地A和B(你可以认为 ...

随机推荐

  1. (7)UI(基础对象)

    1.地图控件:   地图控件可支持导入Tiled地图编辑器导出的tmx格式文件,地图是制作游戏关卡地形图的控件,对于即时战略类型游戏的制作,为了使玩家流畅的切换游戏画面,经常会使用超过屏幕尺寸的地图. ...

  2. 在C#中开启事务

    1.为什么要开启事务: 举一个简单的例子:在银行业务中,有一条记账原则,即又借有贷.为了保证这种原则,每发生一笔银行业务,就必须保证会计账目上借方科目和贷方科目至少个少一笔,并且这两笔要么同时成功,要 ...

  3. 第19章 使用PXE+Kickstart部署无人值守安装

    章节概述: 本章节将教会您通过PXE+DHCP+TFTP+VSftpd+Kickstart服务程序搭建出无人值守安装系统,从而批量部署客户机系统. 这种系统能够实现自动化运维.避免了重复性劳动,帮助提 ...

  4. xcode6以后, 使用.pch

    http://blog.csdn.net/lihuiqwertyuiop/article/details/39268101 总结: . 创建.pch文件 . Apple LLVM 6.1 - Lang ...

  5. Android控件之圆形Button

    bg_circle.xml <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns: ...

  6. DICOM:Ubuntu14环境下安装dcm4chee+oviyam2.1

    背景: 之前博文DICOM:开源DICOM服务框架DCM4CHEE安装中曾介绍过在Windows7环境下安装部署dcm4chee.近期公司项目需要与部署到Linux系统的远端基于dcm4chee框架的 ...

  7. FastMM的安装方法

    FastMM 快速在D2006和2007中已代替了原来的内存管理器.D7也可以使用,而且很方便哦.请看步骤: 1. FastMM是开源项目,去她老家先拖个来. http://sourceforge.n ...

  8. django动态表格总结

    应用场景: A与B之间存在一对多关系. CBV实现方案: CreateView/UpdateView + inlineformset + jquery 具体: view方面:重写post/get方法, ...

  9. Having与Where的区别

    where 子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,where条件中不能包含聚组函数,使用where条件过滤出特定的行. having 子句的作用是筛 ...

  10. CI邮箱中SMTP的一些端口

    介绍其他几个常用邮箱设置,并以网易126邮箱为例,发图.        一.新浪邮箱(1)新浪邮箱自08年6月分服务器被攻击后开始对pop取件频率进行了严格**,同时新注册的用户需要手动才能开通pop ...