IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 深度优先搜索- -简单版 -> 正文阅读

[数据结构与算法]深度优先搜索- -简单版

在图上寻找路径

int main() {
?? ?//将所有点都标记为新点;
?? ?//起点 = 1;
?? ?//终点 = 8;
?? ?cout << Dfs(起点);
}

判断从V出发能否找到终点

bool Dfs(V) {//从V出发判断是否能到终点
	if (V是终点)
		return true;
	if (V是旧点)
		return false;
	将V标记为旧点
	对和V相邻的每个节点U{
		if (Dfs(U) == true)
			return true;
		}
	 return false;
}

判断从V出发能否走到终点,如果能,要记录路径

Node path[MAX_LEN];//MAX_LEN取节点总数即可
int depth;
bool Dfs(V) {//从V出发进行遍历
	if (V是终点) {
		path[depth] = V;
		return true;
	}
	if (V是旧点) {
		return false;
	}
	将V标记为旧点;
	path[depth] = V;
	depth++;
	对和V相邻的每个节点U{
		if (Dfs(U) == true)
		return 0;
	}
	--depth;
	return false;
}
int main() {
	将所有点标记为新点;
	depth = 0;
	if (Dfs(起点)) {
		for (int i = 0; i <= depth; i++)
			cout << path[i] << endl;
	}
}

遍历图上所有节点

Dfs(V) {//从V出发进行遍历
	if (V是旧点) {
		return;
	}
	将V标记为旧点;
	对和V相邻的每个点U{
		Dfs(U);
	}
}
int main() {
	将所有点都标记为新点;
	while (在图中能找到新点k) {
		Dfs(k);
	}
}

邻接矩阵

G[i][j]可以是自定义类型,可以是int,也可以是struct?

?邻接表

?城堡问题

1817:城堡问题??????

总时间限制:?

1000ms

内存限制:?

65536kB

描述

     1   2   3   4   5   6   7  
   #############################
 1 #   |   #   |   #   |   |   #
   #####---#####---#---#####---#
 2 #   #   |   #   #   #   #   #
   #---#####---#####---#####---#
 3 #   |   |   #   #   #   #   #
   #---#########---#####---#---#
 4 #   #   |   |   |   |   #   #
   #############################
           (图 1)

   #  = Wall   
   |  = No wall
   -  = No wall


图1是一个城堡的地形图。请你编写一个程序,计算城堡一共有多少房间,最大的房间有多大。城堡被分割成m?n(m≤50,n≤50)个方块,每个方块可以有0~4面墙。

输入

程序从标准输入设备读入数据。第一行是两个整数,分别是南北向、东西向的方块数。在接下来的输入行里,每个方块用一个数字(0≤p≤50)描述。用一个数字表示方块周围的墙,1表示西墙,2表示北墙,4表示东墙,8表示南墙。每个方块用代表其周围墙的数字之和表示。城堡的内墙被计算两次,方块(1,1)的南墙同时也是方块(2,1)的北墙。输入的数据保证城堡至少有两个房间。

输出

城堡的房间数、城堡中最大房间所包括的方块数。结果显示在标准输出设备上。

样例输入

4 
7 
11 6 11 6 3 10 6 
7 9 6 13 5 15 5 
1 10 12 7 13 7 5 
13 11 10 8 10 12 13 

样例输出

5
9

?思路:西墙1 :1;北墙2:10;东墙4:100;南墙8:1000.

每个方块有几面墙,二进制数位运算。

方块看作节点,相邻方块之间没有墙,则视为有边相连。房间数:所有极大连通子图数目;最大房间:所有极大连通子图中节点最多的那个

?对每一个房间,进行深搜,可以得到该节点所在的极大连通子图。房间数目- -染色,用的颜色种类

#include <iostream>
using namespace std;
int R, C;//行列数
int rooms[60][60];//存储图的信息
int color[60][60];//方块是否染过色的标记 标记
int maxRoomArea = 0, roomNum = 0;//最大的面积,房间数目
int roomArea;//正在探索的连通子图面积
void Dfs(int i, int k) {
	//从节点(i,k)出发,进行深度优先搜索
	//即搜素该节点所在的极大连通子图
	if (color[i][k])//递归结束
		return;
	roomArea++;//该方块加入房间,面积加1
	color[i][k] = roomNum;
	//对和(i,j)节点相邻的节点进行深搜
	//西墙1 :1;北墙2:10;东墙4:100;南墙8:1000
	if ((rooms[i][k] & 1) == 0&&k-1>=1)//向西走且不出界
		Dfs(i, k - 1);
	if ((rooms[i][k] & 2) == 0&&i-1>=1)//向北走且不出界
		Dfs(i - 1, k);
	if ((rooms[i][k] & 4) == 0&&k+1<=C)//向东走且不出界
		Dfs(i, k + 1);
	if ((rooms[i][k] & 8) == 0&&i+1<=R)//向南走且不出界
		Dfs(i + 1, k);
}
int main() {
	cin >> R >> C;
	for (int i = 1; i <= R; i++)
		for (int k = 1; k <= C; k++)
			cin >> rooms[i][k];
	memset(color, 0, sizeof(color));//所有点都标记为新点
	for (int i = 1; i <= R; i++)
		for (int k = 1; k <= C; k++) {//循环遍历所有的点
			if (!color[i][k]) {//没有染色标记- - 在图中能找到新点
				roomNum++;//找到了新的极大连通子图-新房间
				roomArea = 0;
				Dfs(i, k);//深搜
				maxRoomArea =
					max(roomArea, maxRoomArea);
			}
		}
	cout << roomNum << endl;
	cout << maxRoomArea << endl;
	//复杂度 O(R*C)
}

?踩方格

有一个方格矩阵,矩阵边界在无穷远处。我们做如下假设:

a. 每走一步时,只能从当前方格移动一格,走到某个相邻的方格上;
b. 走过的格子立即塌陷无法再走第二次;
c. 只能向北、东、西三个方向走;

请问:如果允许在方格矩阵上走?n?步,共有多少种不同的方案。

2?种走法只要有一步不一样,即被认为是不同的方案。

输入格式

允许在方格上行走的步数?n(n≤20)。

输出格式

计算出的方案数量。

输出时每行末尾的多余空格,不影响答案正确性

样例输入

2

样例输出

7

思路:

递归-- - 分类讨论

从(i,j)出发,走n步的方案数,等于以下三项的和:

1)下一步向北走,走到(i-1,j),然后从(i-1,j)走n-1步的方案数;前提(i-1,j)还没有走过

2)下一步向东走,走到(i,j+1),然后从(i,j+1)走n-1步的方案数;前提(i,j+1)还没有走过

3)下一步向西走,走到(i,j-1),然后从(i,j-1)走n-1步的方案数 。前提(i,j-1)还没有走过

再分析- - 深度优先搜索

从(i,j)出发,走n步的方案数(从(i,j)出发遍历),等于以下三项的和:

1)下一步向北走,走到(i-1,j),然后从(i-1,j)走n-1步的方案数;前提(i-1,j)还没有走过- - 相邻的新点

2)下一步向东走,走到(i,j+1),然后从(i,j+1)走n-1步的方案数;前提(i,j+1)还没有走过- - 相邻的新点

3)下一步向西走,走到(i,j-1),然后从(i,j-1)走n-1步的方案数 。前提(i,j-1)还没有走过- - 相邻的新点

递归边界: n等于0时,从(i,j)出发,走0步的方案数只有一种,就是走0步

?

#include <iostream>
using namespace std;
int visited[100][100];
int ways(int i, int j, int n) {
	//从点(i,j)出发,走n步的方案数- - 从某节点出发,遍历
	if (n == 0)
		return 1;
	visited[i][j] = 1;//标记为旧点
	int num = 0;
	if (!visited[i][j - 1])//向西走
		num += ways(i, j - 1, n - 1);
	if (!visited[i][j + 1])//向东走
		num += ways(i, j + 1, n - 1); 
	if (!visited[i - 1][j])//向北走
		num += ways(i - 1, j, n - 1);
	//以上求出了在先从(i,j)走的情况下,所有的情况
	//既然已经求出了这个num了,我们就应该撤去对(i,j)的标记
	//先走(m,n)的情况下,还可以再走(i,j),
	//前提是,在走(m,n)之前,没有走过(i,j)
	visited[i][j] = 0;//
	return num;
}
int main() {
	int n;
	cin >> n;
	//全部置为新点
	memset(visited, 0, sizeof(visited));

	//平面无限大,可以任选起点,
	//从(25,25)出发,走不超过20步不越界- - 省去判断
	cout << ways(25, 25, n) << endl;
	return 0;
}

一个状态,相当于图上的一个节点,(i,j,n)节点,与状态(i,j,n)相邻的状态是(i-1,j,n-1)、(i,j-1,n-1)、(i,j+1,n-1),相邻表示有边。

在一个图上,从节点(x,y,n)出发,其中x,y任选,n是20,走到一些目标节点(x1,y1,0),求一共有多少种走法。深搜,从图上的节点出发(某个状态),走到某个目标节点或者某些目标节点(某个或者某些状态),求解一共有多少种走法,或者最近路径,或者权值最小,等等。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-02-14 21:25:47  更:2022-02-14 21:28:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 17:30:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码