前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >最少联通代价(dfs+曼哈顿距离)

最少联通代价(dfs+曼哈顿距离)

作者头像
Ch_Zaqdt
发布2019-01-10 17:08:48
8830
发布2019-01-10 17:08:48
举报
文章被收录于专栏:Zaqdt_ACM

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

Hint

1<=N,M<=50

       这道题有两种做法,一种是先用dfs去区分两个连通块,然后再用bfs去跑两个连通块相连的最小值;另一种方法是运用了曼哈顿的思想,我们先用dfs去把每个连通块的坐标存起来,然后去遍历两个连通块的坐标的最小曼哈顿距离就好了。

       不得不说第二种方法角度刁钻思路惊奇...


Code:

代码语言:javascript
复制
#include <bits/stdc++.h>
#define maxn 55
#define inf 0x3f3f3f3f
using namespace std;
char pre[maxn][maxn];
struct Node{
	int x,y;
}Edge;
vector<Node> v[2];
int dir[4][2] = {1,0,0,1,-1,0,0,-1};
int n,m,s;

bool Check(int x,int y){
	if(x >= 0 && y >= 0 && x < n && y < m && pre[x][y] == 'X')return true;
	return false;
}

void dfs(int x,int y){
	pre[x][y] = '.';
	Edge.x = x;
	Edge.y = y;
	v[s].push_back(Edge);
	for(int i=0;i<4;i++){
		int xx = x + dir[i][0];
		int yy = y + dir[i][1];
		if(Check(xx, yy)){
			dfs(xx, yy);
		}
	}
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		scanf("%s",pre[i]);
	}
	s = 0;
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			if(pre[i][j] == 'X'){
				dfs(i,j);
				s ++;
			}
		}
	}
	int ans = inf;
	for(int i=0;i<v[0].size();i++){
		for(int j=0;j<v[1].size();j++){
			ans = min(ans, abs(v[0][i].x - v[1][j].x) + abs(v[0][i].y - v[1][j].y) - 1);
		}
	}
	printf("%d\n",ans);
	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年10月30日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档