【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个正 整 ...
随机推荐
- 【详细】Python基础(一)
@ 目录 前言 1. Python环境的搭建 1.1 python解释器的安装 1.2 pycharm的安装 2. Python基础语法 2.1 基本语法 2.2 数据类型 2.3 标识符与关键字 2 ...
- 【C++】《Effective C++》第二章
第二章 构造/析构/赋值运算 条款05:了解C++默默编写并调用哪些函数 默认函数 一般情况下,编译器会为类默认合成以下函数:default构造函数.copy构造函数.non-virtual析构函数. ...
- Python利用最优化算法求解投资内部收益率IRR【一】
一. 内部收益率和净现值 内部收益率(Internal Rate of Return, IRR)其实要和净现值(Net Present Value, NPV)结合起来讲.净现值指的是某个投资项目给公司 ...
- CS远控
Cobaltstrike 一.基础使用 ./teamserver 192.168.43.224 123456 启动服务器端 在windows下的链接 双击bat文件即可 在linux下 ./start ...
- Electron实用技巧-开机启动时隐藏主窗口,只显示系统托盘
# 1 在桌面软件中,开机自启动是很常见的功能,在electron中也提供了很好的支持,以下是主要代码: //应用是否打包if (app.isPackaged) { //设置开机启动 app.se ...
- Spring集成GuavaCache实现本地缓存
Spring集成GuavaCache实现本地缓存: 一.SimpleCacheManager集成GuavaCache 1 package com.bwdz.sp.comm.util.test; 2 3 ...
- Java 8中字符串拼接新姿势:StringJoiner
介绍 StringJoiner是java.util包中的一个类,用于构造一个由分隔符分隔的字符序列(可选),并且可以从提供的前缀开始并以提供的后缀结尾.虽然这也可以在StringBuilder类的帮助 ...
- 自导自演的面试现场,趣学MySQL的10种文件
导读 Hi,大家好!我是白日梦!本文是MySQL专题的第 24 篇. 今天我要跟你分享的MySQL话题是:"自导自演的数据库面试现场--谈谈MySQL的10种文件" 换一种写作风格 ...
- UNIX DOMAIN SOCKETS IN GO unix域套接字
Unix domain sockets in Go - Golang News https://golangnews.org/2019/02/unix-domain-sockets-in-go/ pa ...
- A1Z26 Cipher - Letter Number A=1 B=2 C=3 - Online Decoder, Translator https://www.dcode.fr/letter-number-cipher
A1Z26 Cipher - Letter Number A=1 B=2 C=3 - Online Decoder, Translator https://www.dcode.fr/letter-nu ...