【hdu 4859】海岸线(图论--网络流最小割)
题意:有一个区域,有'.'的陆地,'D'的深海域,'E'的浅海域。其中浅海域可以填充为陆地。这里的陆地区域不联通,并且整个地图都处在海洋之中。问填充一定浅海域之后所有岛屿的最长的海岸线之和。
解法:最小割。从“分隔”陆地和海域可以想到“割”的概念,然后我们先不考虑浅海域,要深海域和陆地的对数尽量大,也就是相同的地理构造对数尽量小。
于是我们建立一个二分图,深海域和陆地都分列两侧,对于相邻的一个在左,一个在右,也就是“行+列”是奇数的放左,偶数的在右。而对于相邻的深海域和陆地,它们在图中理应分列两侧,才有“相连”的意义。(唉,我算是“梗着脖子”地在解释......~(-仝-)~)于是可以深海域的奇数的在左,而陆地的偶数的在左。
接着建立一个源点和汇点,左侧的点与源点相连,右侧的点与汇点相连。由于无约束,边容量为INF。而4个方向相邻的都“相连”,便建边,容量为1,表示割这条边的代价就是1。又因为这整个地图都处在海洋之中,也就是这个地图外围是一圈深海域,这是隐含条件,所以还需要另外建这些点和对应的边。
最后,用最大流算法求出最小割,表示相同的地理构造的最少的对数,而最长的海岸线就是最多的不同的构造,也就是总对数-最少的相同的地理构造的对数。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 #include<queue>
6 using namespace std;
7
8 const int N=50,NN=3000,MM=30000,INF=20000;
9 int n,m,len=1;
10 int last[NN],d[NN];
11 int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
12 char s[N][N];
13 struct node{int x,y,fl,next;}a[MM];
14 queue<int> q;
15
16 int mmin(int x,int y) {return x<y?x:y;}
17 void ins(int x,int y,int fl)
18 {
19 a[++len].x=x,a[len].y=y,a[len].fl=fl;
20 a[len].next=last[x],last[x]=len;
21 a[++len].x=y,a[len].y=x,a[len].fl=0;
22 a[len].next=last[y],last[y]=len;
23 }
24 bool bfs(int st,int ed)
25 {
26 while (!q.empty()) q.pop();
27 memset(d,0,sizeof(d));
28 q.push(st); d[st]=1;
29 while (!q.empty())
30 {
31 int x=q.front(); q.pop();
32 for (int i=last[x];i;i=a[i].next)
33 {
34 int y=a[i].y;
35 if (!a[i].fl||d[y]) continue;
36 d[y]=d[x]+1; q.push(y);
37 }
38 }
39 return d[ed];
40 }
41 int dfs(int x,int flow,int ed)
42 {
43 if (x==ed) return flow;
44 int sum=0;
45 for (int i=last[x];i;i=a[i].next)
46 {
47 int y=a[i].y;
48 if (d[y]!=d[x]+1||!a[i].fl) continue;
49 int t=dfs(y,mmin(flow-sum,a[i].fl),ed);
50 sum+=t;
51 a[i].fl-=t,a[i^1].fl+=t;
52 if (sum==flow) break;
53 }
54 if (!sum) d[x]=0;
55 return sum;
56 }
57 int Max_flow(int st,int ed)
58 {
59 int sum=0;
60 while (bfs(st,ed)) sum+=dfs(st,INF,ed);
61 return sum;
62 }
63 int ID(int x,int y) {return (x-1)*m+y;}
64 int main()
65 {
66 int T;
67 scanf("%d",&T);
68 for (int kase=1;kase<=T;kase++)
69 {
70 scanf("%d%d",&n,&m);
71 for (int j=1;j<=m+2;j++) s[1][j]='D';
72 for (int i=2;i<=n+1;i++)
73 {
74 scanf("%s",s[i]+2);
75 s[i][1]=s[i][m+2]='D';
76 }
77 for (int j=1;j<=m+2;j++) s[n+2][j]='D';
78 n+=2,m+=2;
79
80 int st=n*m+1,ed=n*m+2;
81 memset(last,0,sizeof(last));
82 len=1;
83 for (int i=1;i<=n;i++)
84 {
85 for (int j=1;j<=m;j++)
86 {
87 if (i==1||i==n||j==1||j==m) s[i][j]='D';
88 int t=ID(i,j);
89 if (s[i][j]=='.')
90 {
91 if ((i+j)%2) ins(st,t,INF);
92 else ins(t,ed,INF);
93 }
94 if (s[i][j]=='D')
95 {
96 if ((i+j)%2) ins(t,ed,INF);
97 else ins(st,t,INF);
98 }
99 for (int k=0;k<4;k++)
100 {
101 int x=i+dx[k],y=j+dy[k],tt=ID(x,y);
102 if (x<1||y<1||x>n||y>m) continue;
103 ins(t,tt,1);
104 }
105 }
106 }
107 int ans=Max_flow(st,ed);
108 ans=(n-1)*m+(m-1)*n-ans;
109 printf("Case %d: %d\n",kase,ans);
110 }
111 return 0;
112 }
【hdu 4859】海岸线(图论--网络流最小割)的更多相关文章
- 图论--网络流--最小割 HDU 2485 Destroying the bus stations(最短路+限流建图)
Problem Description Gabiluso is one of the greatest spies in his country. Now he's trying to complet ...
- 【HDU4859】 海岸线(网络流-最小割)
Problem Description 欢迎来到珠海! 由于土地资源越来越紧张,使得许多海滨城市都只能依靠填海来扩展市区以求发展.作为Z市的决策人,在仔细观察了Z市地图之后,你准备通过填充某些海域来扩 ...
- 【LA 3487】Duopoly(图论--网络流最小割 经典题)
题意:C公司有一些资源,每种只有1个,有A.B两个公司分别对其中一些资源进行分组竞标,每组竞标对一些资源出一个总价.问C公司的最大收益. 解法:最小割.将A公司的竞标与源点相连,B公司的与汇点相连,边 ...
- 【uva 1515】Pool construction(图论--网络流最小割 模型题)
题意:有一个水塘,要求把它用围栏围起来,每个费用为b.其中,(#)代表草,(.)代表洞,把一个草变成洞需要费用d, 把一个洞变成草需要费用f.请输出合法方案中的最小费用. 解法:(不好理解...... ...
- 【bzoj2229】[Zjoi2011]最小割 分治+网络流最小割
题目描述 小白在图论课上学到了一个新的概念——最小割,下课后小白在笔记本上写下了如下这段话: “对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分中,则称这个划分 ...
- 【题解】 bzoj3894: 文理分科 (网络流/最小割)
bzoj3894,懒得复制题面,戳我戳我 Solution: 首先这是一个网络流,应该还比较好想,主要就是考虑建图了. 我们来分析下题面,因为一个人要么选文科要么选理科,相当于两条流里面割掉一条(怎么 ...
- 【bzoj3774】最优选择 网络流最小割
题目描述 小N手上有一个N*M的方格图,控制某一个点要付出Aij的代价,然后某个点如果被控制了,或者他周围的所有点(上下左右)都被控制了,那么他就算是被选择了的.一个点如果被选择了,那么可以得到Bij ...
- 【bzoj1143】[CTSC2008]祭祀river Floyd+网络流最小割
题目描述 在遥远的东方,有一个神秘的民族,自称Y族.他们世代居住在水面上,奉龙王为神.每逢重大庆典, Y族都会在水面上举办盛大的祭祀活动.我们可以把Y族居住地水系看成一个由岔口和河道组成的网络.每条河 ...
- 【bzoj1797】[Ahoi2009]Mincut 最小割 网络流最小割+Tarjan
题目描述 给定一张图,对于每一条边询问:(1)是否存在割断该边的s-t最小割 (2)是否所有s-t最小割都割断该边 输入 第一行有4个正整数,依次为N,M,s和t.第2行到第(M+1)行每行3个正 整 ...
随机推荐
- HSRP技术(热备份)学习总结
热备份学习视频https://www.bilibili.com/video/BV1i7411G7vm?p=78 • 命令: ○ int fa0/x ○ standby 1 ...
- Centos 6 下安装 OSSEC-2.8.1 邮件告警 (二)
Ossec 配置邮件通知 ## 1 安装软件包: yum install -y sendmail mailx cyrus-sasl cyrus-sasl-plain #安装postfix邮件相关的软件 ...
- Web安全之CSRF(跨站请求伪造)
CSRF(跨站请求伪造)概述 Cross-site request forgery 简称为"CSRF",在CSRF的攻击场景中攻击者会伪造一个请求(这个请求一般是一个链接),然后欺 ...
- scp等不需要存入know_host
1.修改sshd的配置文件 vi /etc/ssh/ssh_config 修改为如下 StrictHostKeyChecking no UserKnownHostsFile /dev/null 重启s ...
- nodejs中使用worker_threads来创建新的线程
目录 简介 worker_threads isMainThread MessageChannel parentPort和MessagePort markAsUntransferable SHARE_E ...
- Zju1100 Mondriaan
题目描述 有一个m行n列的矩阵,用1*2的骨牌(可横放或竖放)完全覆盖,骨牌不能重叠,有多少种不同的覆盖的方法? 你只需要求出覆盖方法总数mod p的值即可. 输入格式 三个整数数n,m,p,m< ...
- 大数据系列1:一文初识Hdfs
最近有位同事经常问一些Hadoop的东西,特别是Hdfs的一些细节,有些记得不清楚,所以趁机整理一波. 会按下面的大纲进行整理: 简单介绍Hdfs 简单介绍Hdfs读写流程 介绍Hdfs HA实现方式 ...
- 你真的了解Android系统启动流程吗?Android高级工程师必看系列,已开源
前言 从毕业到现在面试也就那么几家公司,单前几次都比较顺利,在面到第三家时都给到了我offer!前面两次找工作,没考虑到以后需要什么,自己的对未来的规划是什么,只要有份工作,工资符合自己的要求就行!所 ...
- IDEA SSM后端框架入门
SSM框架 如果对SSM一无所知,推荐先去看这本书,可以在微信读书上看. 知识点 控制器返回对象时,对象需要有getter,setter方法,才能自动转化为json数据类型. 一个服务管理者对应多个业 ...
- memset 在c++中使用细节注意
C语言,在利用struct进行数据封装时,经常会使用memset(this,0,sizeof(*this))来初始化.而C++中,有时候也会用到struct,在利用memset进行初始化时,非常容易踩 ...