题目描述

输入输出格式

输入格式:

输出格式:

输入输出样例

输入样例#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. linux链路聚合

    配置聚合连接(网卡绑定,链路聚合): eth0 ================>>虚拟网卡team eth1 配置聚合连接 [root@Centos7-Server ~]# nmcli ...

  2. Mysql升级过程的问题

    升级安装5.6版本mysql linux环境下的yum默认mysql版本是5.1的,由于项目需要保存表情等4个字节的数据,版本受限,需要升级到5.6版本支持utf8mb4格式的编码. 升级过程大概就是 ...

  3. phpspider 的简单使用

    phpspider 的简单使用 phpspider是一款PHP开发蜘蛛爬虫框架. 官方github下载地址:https://github.com/owner888/phpspider官方文档下载地址: ...

  4. MINA 框架总结 整体理解

    MINA是一套成熟的JAVA NIO 框架,在用到Socket通信的Java应用场景中经常会得到使用.其作者还有一套更加知名的框架Netty,其应用程度更加广泛.虽然不及Netty知名,Mina也是一 ...

  5. eclipse全选包

    按住shift键,点击第一个jar包,然后点击最后一个jar包,就全选了所有jar包,然后添加build path 添加到类路径

  6. Python学习 :六个标准数据类型

    一.Numbers(数字类型) 数字类型主要分为两种—— 整数(Integer)与 浮点数(Float) 整数分为整型和长整型(在Python3中已经不再区分为整型与长整型,统一称为整型) 注意:数字 ...

  7. (原创)用Verilog实现一个参数化的呼吸灯(Verilog,CPLD/FPGA)

    1.Abstract     观察到一个有趣的现象,每当把Apple笔记本合上的时候,那个白色的呼吸灯就会反复地由暗渐明,然后又由明渐暗,乍一看就像Apple笔记本在打盹休息一样,十分可爱!于是突发奇 ...

  8. JENKINS系统的安装部署

    JENKINS 安装使用文档 简介 Jenkins是一个功能强大的应用程序,允许持续集成和持续交付项目,无论用的是什么平台.这是一个免费的源代码,可以处理任何类型的构建或持续集成,集成Jenkins可 ...

  9. 自定义T4模板去掉实体对象中的下划线

            在EF Power Tool 默认使用的T4模板中,如果数据库表有下划线,那么生成的实体也有下划线,但是我们实际使用的过程中,是不希望有下划线的,要解决这个问题,可以自定义这个T4模板 ...

  10. 【多线程】 Task

    [多线程] Task 一. 常用方法: 1. ContinueWith : 当前 Task 完成后, 执行传入的 Task 2. Delay : 创建一个等待的 Task,只有在调用 Wait 方法时 ...