Description

在一个 N 行 M 列的字符网格上, 恰好有 2 个彼此分开的连通块。每个连通 块的一个格点与它的上、下、左、右的格子连通。如下图所示:

现在要把这 2 个连通块连通, 求最少需要把几个’.’转变成’X’。上图的例子中, 最少只需要把 3个’.’转变成’X’。下图用’*’表示转化为’X’的格点。

Input

第 1 行:2 个整数 N 和 M(1<=N,M<=50) 接下来 N 行,每行 M 个字符, ’X’表示属于某个连通块的格点,’.’表示不属于某 个连通块的格点

Output

第 1 行:1 个整数,表示最少需要把几个’.’转变成’X’

Sample Input

6 16
…………….
..XXXX….XXX…
…XXXX….XX…
.XXXX……XXX..
……..XXXXX…
………XXX….

Sample Output

3


思路简析

法一:先用一个小深搜区分出两个连通块的点,再用广搜搜出每个连通块1的点到每个连通块2的点上的距离,每次用min()更新最小值。
代码实现如下(找的一位Pal帮忙打的,还是有点儿良心特此声明):

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,pre[1000000],a[1000000],b[1000000],minn,ans=1e10;
int x[4]={1,-1,0,0},y[4]={0,0,1,-1};
char map[100][100];
bool mark[100][100];
bool check(int s,int t)
{if(s&&t&&s<=n&&t<=m&&!mark[s][t]&&map[s][t]!='S') return 1;return 0;
}
void fun(int d)
{minn++;if(pre[d]) fun(pre[d]);
}
void bfs(int r,int c)
{memset(mark,0,sizeof(mark));minn=0;int head=0,tail=1;int nextr,nextc;mark[r][c]=1;pre[1]=0;a[1]=r;b[1]=c;while(head!=tail){head++;for(int i=0;i<4;i++){nextr=a[head]+x[i];nextc=b[head]+y[i];if(check(nextr,nextc)){tail++;a[tail]=nextr;b[tail]=nextc;mark[nextr][nextc]=1;pre[tail]=head;if(map[nextr][nextc]=='X'){fun(tail);ans=min(minn,ans);}}}}
}
void dfs(int r,int c)
{for(int i=0;i<4;i++)if(check(r+x[i],c+y[i])&&map[r+x[i]][c+y[i]]!='.'){mark[r+x[i]][c+y[i]]=1;map[r+x[i]][c+y[i]]='S';dfs(r+x[i],c+y[i]);mark[r+x[i]][c+y[i]]=0;}
}
void f()
{for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(map[i][j]=='X'){dfs(i,j);map[i][j]='S';return ;}
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%s",map[i]+1);bool flag=1;f();for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(map[i][j]=='S')bfs(i,j);printf("%d",ans-2);
}

法二:也同样用一个小深搜,记录下两个连通块分别的各自坐标,再用曼哈顿距离的思想枚举每个连通块1上的点到每个连通块2上的点上的距离,求出最小值。
干货:详解曼哈顿距离及其代替广搜的原因
但这道题应是曼哈顿距离-1,因为它并不是要求路径步数,而是求联通代价,当距离第二个连通块还剩一步的时候,就已经达成目标了,不用走到第二个连通块上去,所以要少一步。
代码实现如下:

#include<cstdio>
#include<cmath>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
char a[55][55];//存“地图”
int n,m/*长、宽*/,ans=1e8/*顾名思义*/,xx[4]={-1,0,0,1},yy[4]={0,-1,1,0}/*移动方向*/,s/*表示现在搜到的是第几个连通块*/;
struct node{int x1,y1;
}temp;//结构体记录下坐标,temp用来将坐标存入结构体,放进数组
vector<node>f[2];//由于不确定连通块1、2分别有多少个点,所以用动态数组存储//其实很简单,待会儿结尾放一个超链接
void dfs(int x, int y)
{a[x][y]='.';//避免重复搜索temp.x1=x;temp.y1=y;f[s].push_back(temp);//记录坐标,放进数组里for(int i=0;i<4;i++)//拓展四周联通的连通块点做处理{int fx=x+xx[i],fy=y+yy[i];if(fx>=0&&fx<n&&fy>=0&&fy<m&&a[fx][fy]=='X')dfs(fx,fy);}
}
int main()
{scanf("%d %d",&n,&m);for(int i=0;i<n;i++)scanf("%s",a[i]);//读取一行字符
/*忽然想到补充一点,如果从[1]开始的话,应该这么写:for(int i=1;i<=n;i++)scanf("%s",a[i]+1);a[i]就是地址,+1就是往后一个存(数组的地址是连续的)
*/for(int i=0;i<n;i++)for(int j=0;j<m;j++)if(a[i][j]=='X')//搜到一个连通块{dfs(i,j);s++;//连通块+1}for(int i=0;i<f[0].size();i++)for(int j=0;j<f[1].size();j++)ans=min(ans,int(fabs(f[0][i].x1-f[1][j].x1)+fabs(f[0][i].y1-f[1][j].y1)-1));//利用曼哈顿距离思想求解printf("%d",ans);return 0;
}

最少联通代价【曼哈顿距离】相关推荐

  1. 曼哈顿距离(Manhattan Distance )详解

    概念 曼哈顿距离--两点在南北方向上的距离加上在东西方向上的距离,即d(i,j)=|xi-xj|+|yi-yj|.对于一个具有正南正北.正东正西方向规则布局的城镇街道,从一点到达另一点的距离正是在南北 ...

  2. 曼哈顿距离(值得收藏)

    曼哈顿距离 定义 出租车几何或曼哈顿距离(Manhattan Distance)是由十九世纪的赫尔曼·闵可夫斯基所创词汇 ,是种使用在几何度量空间的几何学用语,用以标明两个点在标准坐标系上的绝对轴距总 ...

  3. 曼哈顿距离最小生成树

    一.参考博客 博客:曼哈顿距离最小生成树与莫队算法 博客:学习总结:最小曼哈顿距离生成树 二.前置知识 1.曼哈顿距离:给定二维平面上的N个点,在两点之间连边的代价.(即distance(P1,P2) ...

  4. 曼哈顿距离最小生成树与莫队算法(总结)

    曼哈顿距离最小生成树与莫队算法(总结) 1 曼哈顿距离最小生成树 曼哈顿距离最小生成树问题可以简述如下:  给定二维平面上的N个点,在两点之间连边的代价为其曼哈顿距离,求使所有点连通的最小代价.  朴 ...

  5. 简单粗暴理解与实现机器学习之K-近邻算法(三):距离度量、欧氏距离、曼哈顿距离、切比雪夫距离、闵可夫斯基距离、标准化距离、余弦距离、汉明距离、杰卡德距离、马氏距离

    K-近邻算法 文章目录 K-近邻算法 学习目标 1.3 距离度量 1 欧式距离**(Euclidean Distance):** 2 **曼哈顿距离(Manhattan Distance):** 3 ...

  6. 各种距离 欧式距离、曼哈顿距离、切比雪夫距离、闵可夫斯基距离、标准欧氏距离、马氏距离、余弦距离、汉明距离、杰拉德距离、相关距离、信息熵...

    1. 欧氏距离(Euclidean Distance) 欧氏距离是最容易直观理解的距离度量方法,我们小学.初中和高中接触到的两个点在空间中的距离一般都是指欧氏距离. 二维平面上点a(x1,y1)与b( ...

  7. 曼哈顿距离最小生成树莫队算法

    参考资料:https://www.cnblogs.com/CsOH/p/5904430.html https://blog.csdn.net/huzecong/article/details/8576 ...

  8. c语言15-puzzle解法,15 Puzzle (4乘4谜题) IDA*(DFS策略与曼哈顿距离启发) 的C语言实现...

    大家好!这是我的第一篇博客,由于之前没有撰写博客的经验,并且也是初入计算机和人工智能领域,可能有些表述或者理解不当,还请大家多多指教. 一.撰写目的 由于这个学期在上算法与数据结构课程的时候,其中一个 ...

  9. 欧式距离与曼哈顿距离的区别以及曼哈顿距离的应用

    欧氏距离就是我们最常用的两点之间的直线距离. 以二维空间为例,两点(x1,y1),(x2,y2)之间的欧式距离为: 曼哈顿距离则表示两个点在标准坐标系上的绝对轴距之和. 还是以二维空间为例,两点(x1 ...

  10. 2018东北四省赛 Spin A Web 曼哈顿距离最小生成树

    莫队的论文,讲的很清晰 问题描述:给定平面N个点,两边相连的代价为曼哈顿距离,求这些点的最小生成树 按一般想法,prime复杂度O(n^2),Kruskal复杂度O(n^2 logn),N很大时,这复 ...

最新文章

  1. linux环境下监控日志的变化命令 tail -f
  2. [Android组件化]分发模块依赖倒置
  3. Android中Dialog与DialogFragment的对比
  4. 基于python的搜索引擎论文_技术分享 - 基于python构建搜索引擎系列——(四)检索模型...
  5. OpenFOAM流固耦合问题-FsiFoam(foam-extend-4.0)运行tutorials的bug修复
  6. oracle查看登录时间黑屏,oracle 11g默认用户名、密码解锁 以及安装后重启黑屏问题.doc...
  7. 恩墨学院丨OBCP墨天轮精品课正式上线啦~
  8. C++ 关联容器set | map | multiset | multimap
  9. django启动服务器失败-已解决
  10. 公司(企业与市场)与商业模式
  11. 最长上升子序列o(nlogn)复杂度一种简单易懂的理解
  12. 在MingW下编译llvm/clang
  13. JDK8与JDK11
  14. win10 此电脑 网络位置 怎么删除
  15. 井下三专两闭锁的内容_三专两闭锁
  16. 一点知识丨Base64 的图片如何完美复制到系统粘贴板
  17. 架构:短址(short URL)原理及其实现(短地址|短url)
  18. 基于HTML美中华传统文化题材网页项目的设计与实现 (纯HTML+CSS制作中国茶文化网站)...
  19. JavaScript 汉字转拼音
  20. 使用二维数组表示N阶矩阵

热门文章

  1. xctf攻防世界 MISC高手进阶区 很普通的Disco
  2. 模具常用术语中英文对照
  3. kubernetes学习:1.构建harbor镜像仓库
  4. 使用BeautifulSoup进行解析数据
  5. 存在隐患 : 3 racks are required for the erasure coding policies: RS-6-3-1024k. The number of racks is on
  6. Windows 0环和3环通信方式
  7. javascript焦点到文本框内容末尾
  8. VSCODE里调试go
  9. VRML域值的数据类型
  10. 如何搭建部署alertmanager高可用集群?