题目描述

输入输出格式

输入格式:

输出格式:

输入输出样例

输入样例#1:

6 16
................
..XXXX....XXX...
...XXXX....XX...
.XXXX......XXX..
........XXXXX...
..XXX....XXX....
输出样例#1:

4

Solution:

  本题一眼想到搜索(考试时打了半天,没调对~~手动滑稽~~)。事后讨论,发现神佬的思路有可行性也有一些错误,于是从中启发,再结合题解,便改出了类$floyd$的算法。

  首先,用一次$dfs$处理出$3$个连通块并标记,实现比较简单。

  再就是骚操作了,处理出每个$s[i][j]==X$的点所在连通块到其它所有点的最小曼哈顿距离$dis[k][i][j]$(表示第$k$个连通块到$[i,j]$点的最小曼哈顿距离)。

  然后对于每个是连通块上的点(即$s[i][j]==X$的点),去更新这个点所在连通块与其它连通块的最短距离($f[i][j]$表示第$i$个连通块与第$j$个连通块的最短距离),很显然的状态转移方程为:$f[p][q]=min(f[p][q],dis[q][i][j]),\;s[i][j]\in p$,(记得$f[p][q]=f[q][p]$)。

  然后就处理出了$3$个连通块两两之间的最短距离,则$ans$初值是$3$条边中$2$条搭配的最小值(因为要使$3$个连通块连通只要连$2$条边),至于为什么是初值赋值为这个最小值呢?

  那是因为可能存在两两连通块之间共用了点的情况,举个例子:

  $\begin{Bmatrix}
 X\;.\;.\;.\;X\\
 .\;\;.\;.\;.\;\;.\\
 .\;\;.\;.\;.\;\;. \\
 .\;.\;X\;.\;.
\end{Bmatrix}$

  此时求出的$3$个连通块之间的最小距离和为$9$则需要加的$X$个数为$9-2=7$(减$2$是很显然的道理,因为我们是以坐标算曼哈顿距离,两个点之间曼哈顿路径上的点数应该等于曼哈顿距离减$1$(有点类似于小学奥数的植树间隔问题),那么三个点之间实际上就是两个两个点之间的点数,显然是减$2$(怎么感觉自己说的有点绕,~手动滑稽,不信自己模拟~)),但这个例子的答案显然因该是$5$。

  很容易发现,上述情况属于三个连通块之间由非连通块上的点搭桥相连的情况(这不还是$floyd$嘛)。于是我们处理出初值$ans$后,还应该枚举中间点,计算三个点之间共用点搭桥的情况的最小值,更新$ans$。

  那么最后答案就是$ans-2$了。时间复杂度$O(n^3)$(这也只是最坏复杂度,基本体现在预处理枚举每个连通块到其它所有点的最小曼哈顿距离上了),但还是很轻易本题就$AC$了(貌似最优解!)。

  本题给我的启发就是:

  1、其实可以将连通块个数再增多,那么就是跑最小生成树处理初值$ans$,同理继续枚举中间点连接各连通块。

  2、其实$n\leq 50$的数据用此方法还是很水的,可以增大数据至少到$n\leq 200$。

代码:

#include<bits/stdc++.h>
#define il inline
#define ll long long
#define debug printf("%d %s\n",__LINE__,__FUNCTION__)
using namespace std;
int n,m,ans=,p[][],cnt,f[][],tot,dis[][][];
int dx[]={,-,,},dy[]={,,,-};
char s[][];
bool vis[][],lian[];
il void change(int x,int y,int c){
if(vis[x][y])return ;
if(s[x][y]=='X'){vis[x][y]=;p[x][y]=c;}
else return;
for(int i=;i<;i++){
int xx=dx[i]+x,yy=dy[i]+y;
change(xx,yy,c);
}
}
il void dfs(int kuai,int x,int y){
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
dis[kuai][i][j]=min(dis[kuai][i][j],abs(i-x)+abs(j-y));
}
int main()
{
cin>>n>>m;
for(int i=;i<=n;i++)scanf("%s",s[i]+);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(s[i][j]=='X'&&!vis[i][j])change(i,j,++cnt);
memset(dis,0x3f,sizeof(dis));
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(s[i][j]=='X')dfs(p[i][j],i,j);
memset(f,0x3f,sizeof(f));
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(s[i][j]=='X'){
f[p[i][j]][]=min(f[p[i][j]][],dis[][i][j]);
f[p[i][j]][]=min(f[p[i][j]][],dis[][i][j]);
f[p[i][j]][]=min(f[p[i][j]][],dis[][i][j]);
f[][p[i][j]]=f[p[i][j]][];
f[][p[i][j]]=f[p[i][j]][];
f[][p[i][j]]=f[p[i][j]][];
}
ans=min(f[][]+f[][],min(f[][]+f[][],f[][]+f[][]));
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
ans=min(ans,dis[][i][j]+dis[][i][j]+dis[][i][j]);
cout<<ans-;
return ;
}

P2124 奶牛美容的更多相关文章

  1. [洛谷P2124] 奶牛美容

    洛谷题目链接:奶牛美容 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例#1: 6 16 ................ ..XXXX....XXX... ...XXXX... ...

  2. luogu P2124 奶牛美容

    嘟嘟嘟 首先数据范围那么小,那么算法也是相当暴力的. 对于一个点(x, y)所属的联通块,预处理出从这个点出发到这个块外的所有点的曼哈顿距离.复杂度O(n4). 然后求答案:最少答案不一定是三个联通块 ...

  3. [LuoguP2124]奶牛美容_bfs_floyd_曼哈顿距离

    奶牛美容 题目链接:https://www.luogu.org/problem/P2124 数据范围:略. 题解: 发现数据范围只有$50$,显然可以直接$bfs$求出联通块,$floyd$求出相邻两 ...

  4. poj 3614 奶牛美容问题 优先队列

    题意:每头奶牛需要涂抹防晒霜,其中有效的范围 min~max ,现在有L种防晒霜,每种防晒霜的指数为 f 瓶数为 l,问多少只奶牛可以涂上合适的防晒霜?思路: 优先队列+贪心 当奶牛的 min< ...

  5. POJ 3614 Sunscreen (优先队列)

    题意:奶牛美容:有C头奶牛日光浴,每头奶牛分别需要minSPF_i和maxSPF_i单位强度之间的阳光.现有L种防晒霜,分别能使阳光强度稳定为SPF_i,其瓶数为cover_i.求最多满足多少头奶牛 ...

  6. 【bzoj1708】[USACO2007 Oct]Money奶牛的硬币

    题目描述 在创立了她们自己的政权之后,奶牛们决定推广新的货币系统.在强烈的叛逆心理的驱使下,她们准备使用奇怪的面值.在传统的货币系统中,硬币的面值通常是1,5,10,20或25,50,以及100单位的 ...

  7. 【bzoj1231】[Usaco2008 Nov]mixup2 混乱的奶牛

    题目描述 混乱的奶牛[Don Piele, 2007]Farmer John的N(4 <= N <= 16)头奶牛中的每一头都有一个唯一的编号S_i (1 <= S_i <= ...

  8. 【BZOJ1623】 [Usaco2008 Open]Cow Cars 奶牛飞车 贪心

    SB贪心,一开始还想着用二分,看了眼黄学长的blog,发现自己SB了... 最小道路=已选取的奶牛/道路总数. #include <iostream> #include <cstdi ...

  9. COGS130. [USACO Mar08] 游荡的奶牛[DP]

    130. [USACO Mar08] 游荡的奶牛 ★☆   输入文件:ctravel.in   输出文件:ctravel.out   简单对比时间限制:1 s   内存限制:128 MB 奶牛们在被划 ...

随机推荐

  1. 基于socketserver模块实现并发的套接字(tcp、udp)

    tcp服务端:import socketserver class MyHandler(socketserver.BaseRequestHandler): def handle(self): #通信循环 ...

  2. xpath技术解析xm文件(php)

    1.结合php dom技术的学习,得出一个结论:php dom技术可以跨层取出节点,但是不能保持层次关系,使用xpath可以很好地解决问题. *** xpath技术的核心思想:迅速简洁的定位你需要查找 ...

  3. 【c学习-14】

    /*练习*/ #include int testFeiunction(b[],n){ b[1]=1; n=10; } int main(){ int a[10]={1,2,3,4,5}; int n= ...

  4. haystack+Elasticsearch搜素引擎

    搜索引擎原理 通过搜索引擎进行数据查询时,搜索引擎并不是直接在数据库中进行查询,而是搜索引擎会对数据库中的数据进行一遍预处理,单独建立起一份索引结构数据. 我们可以将索引结构数据想象成是字典书籍的索引 ...

  5. 吐血分享:QQ群霸屏技术教程之霸屏实施细则

    小号,再不养,成本抗不住了;QQ群,再不玩,真的就玩不动啦. 霸屏系列,坚持下来差不多10来篇,最近更新的几篇,算是霸屏系列的更新版,毕竟相当的规则变动了. 经营自己,是一种前瞻能力,霸屏十篇,有多少 ...

  6. 利用PHP str_replace()函数替换符合百度MIP内容标准

    了解过百度MIP的同学都知道(什么?你不知道什么是百度MIP?就是移动网页加速器鸭

  7. ExceL按记录导出Txt 工具

    根据客户要求,开发此工具,每一条记录改出一个Txt文本,文本名取其中一字段数据

  8. python-集合类型

    集合具有唯一性(集合中的元素各不相同),无序性,确定性(集合中的元素是不可改变的,不能是列表,字典以及集合本身) 1.add(self, *args, **kwargs),union(self, *a ...

  9. python基础之socket套接字基础part2

    基于UDP的socket 面向无连接的不可靠数据传输,可以没有服务器端,只不过没有服务器端,发送的数据会被直接丢弃,并不能到达服务器端 1 #客户端 2 import socket 3 ip_port ...

  10. Python的异常

    一.异常的常用形式 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行.一般情况下,在Python无法正常处理程序时就会发生一个异常.异常是Python对象,表示一个错误.当Pyth ...