前言
day 56,周二,继续ding~
题目详情
[卡码98] 所有可达路径
题目描述
卡码98 所有可达路径
LeetCode类似题目797 所有可能的路径
解题思路
前提:求解所有可达路径
思路:DFS深度优先搜索
重点:dfs
代码实现
C语言
邻接矩阵
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PATH_MAX_SIZE 50000
#define PATH_MAX_LEN 500
void printRes(int **allPath, int pathSize, int *eachPathSize)
{
for (int i = 0; i < pathSize; i++) {
int resLen = 0;
char res[PATH_MAX_LEN];
memset(res, 0, sizeof(res));
for (int j = 0; j < eachPathSize[i]; j++) {
resLen += sprintf(res + resLen, "%d ", allPath[i][j]);
}
res[resLen - 1] = '\0';
printf("%s\n", res);
}
return ;
}
void savePath(int pathNodeSize, int *pathNode, int **allPath, int *pathSize, int *eachPathSize)
{
allPath[*pathSize] = (int *)malloc(sizeof(int) * pathNodeSize);
memset(allPath[*pathSize], 0, sizeof(int) * pathNodeSize);
for (int i = 0; i < pathNodeSize; i++) {
allPath[*pathSize][i] = pathNode[i];
}
eachPathSize[*pathSize] = pathNodeSize;
(*pathSize)++;
return ;
}
void dfs(int **graph, int graphSize, int index, int *pathNodeSize, int *pathNode, int **allPath, int *pathSize, int *eachPathSize)
{
if (graphSize == index)
{
//退出条件,保存路径
savePath(*pathNodeSize, pathNode, allPath, pathSize, eachPathSize);
return ;
}
// 递归
for (int idx = 1; idx < (graphSize + 1); idx++) {
if (graph[index][idx] == 0) {
continue;
}
pathNode[*pathNodeSize] = idx;
(*pathNodeSize)++;
dfs(graph, graphSize, idx, pathNodeSize, pathNode, allPath, pathSize, eachPathSize);
// 回溯
(*pathNodeSize)--;
}
return ;
}
int main()
{
// 输入
int graphSize = 0;
int graphValSize = 0;
scanf("%d %d", &graphSize, &graphValSize);
//printf("==> %d %d\n", graphSize, graphValSize);
// 邻接矩阵
int **graph = (int **)malloc(sizeof(int *) * (graphSize + 1));
for (int n = 0; n < (graphSize + 1); n++) {
graph[n] = (int *)malloc(sizeof(int) * (graphSize + 1));
memset(graph[n], 0, sizeof(int) * (graphSize + 1));
}
for (int k = 0; k < graphValSize; k++) {
int first = 0;
int last = 0;
scanf("%d %d", &first, &last);
graph[first][last] = 1;
//printf("==> %d %d %d\n", first, last, graph[first][last]);
}
// 处理
// dfs + 队列
int pathSize = 0;
int *eachPathSize = (int *)malloc(sizeof(int) * PATH_MAX_SIZE);
memset(eachPathSize, 0, sizeof(sizeof(int) * PATH_MAX_SIZE));
int **allPath = (int **)malloc(sizeof(int *) * PATH_MAX_SIZE);
memset(allPath, 0, sizeof(int *) * PATH_MAX_SIZE);
// 首元素入队列
int pathNodeSize = 0;
int *pathNode = (int *)malloc(sizeof(int) * (graphSize + 1));
memset(pathNode, 0, sizeof(int) * (graphSize + 1));
pathNode[pathNodeSize++] = 1;
dfs(graph, graphSize, 1, &pathNodeSize, pathNode, allPath, &pathSize, eachPathSize);
// 输出
if (pathSize == 0) {
printf("-1\n");
return 0;
}
printRes(allPath, pathSize, eachPathSize);
return 0;
}
邻接表
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PATH_MAX_SIZE 50000
#define PATH_MAX_LEN 500
void printRes(int **allPath, int pathSize, int *eachPathSize)
{
for (int i = 0; i < pathSize; i++) {
int resLen = 0;
char res[PATH_MAX_LEN];
memset(res, 0, sizeof(res));
for (int j = 0; j < eachPathSize[i]; j++) {
resLen += sprintf(res + resLen, "%d ", allPath[i][j]);
}
res[resLen - 1] = '\0';
printf("%s\n", res);
}
return ;
}
void savePath(int pathNodeSize, int *pathNode, int **allPath, int *pathSize, int *eachPathSize)
{
allPath[*pathSize] = (int *)malloc(sizeof(int) * pathNodeSize);
memset(allPath[*pathSize], 0, sizeof(int) * pathNodeSize);
for (int i = 0; i < pathNodeSize; i++) {
allPath[*pathSize][i] = pathNode[i];
}
eachPathSize[*pathSize] = pathNodeSize;
(*pathSize)++;
return ;
}
void dfs(int **graph, int graphSize, int index, int *graphColSize, int *pathNodeSize, int *pathNode, int **allPath, int *pathSize, int *eachPathSize)
{
if (graphSize == index)
{
//退出条件,保存路径
savePath(*pathNodeSize, pathNode, allPath, pathSize, eachPathSize);
return ;
}
// 递归
for (int idx = 0; idx < graphColSize[index]; idx++) {
pathNode[*pathNodeSize] = graph[index][idx];
(*pathNodeSize)++;
dfs(graph, graphSize, graph[index][idx], graphColSize, pathNodeSize, pathNode, allPath, pathSize, eachPathSize);
// 回溯
(*pathNodeSize)--;
}
return ;
}
int main()
{
// 输入
int graphSize = 0;
int graphValSize = 0;
scanf("%d %d", &graphSize, &graphValSize);
//printf("==> %d %d\n", graphSize, graphValSize);
// 邻接表
int **graph = (int **)malloc(sizeof(int *) * (graphSize + 1));
int *graphColSize = (int *)malloc(sizeof(int) * (graphSize + 1));
memset(graphColSize, 0, sizeof(int) * (graphSize + 1));
for (int n = 0; n < (graphSize + 1); n++) {
graph[n] = (int *)malloc(sizeof(int) * (graphSize + 1));
memset(graph[n], 0, sizeof(int) * (graphSize + 1));
}
for (int k = 0; k < graphValSize; k++) {
int first = 0;
int last = 0;
scanf("%d %d", &first, &last);
graph[first][graphColSize[first]] = last;
graphColSize[first]++;
//printf("==> %d %d %d\n", first, last, graph[first][last]);
}
// 处理
// dfs + 队列
int pathSize = 0;
int *eachPathSize = (int *)malloc(sizeof(int) * PATH_MAX_SIZE);
memset(eachPathSize, 0, sizeof(sizeof(int) * PATH_MAX_SIZE));
int **allPath = (int **)malloc(sizeof(int *) * PATH_MAX_SIZE);
memset(allPath, 0, sizeof(int *) * PATH_MAX_SIZE);
// 首元素入队列
int pathNodeSize = 0;
int *pathNode = (int *)malloc(sizeof(int) * (graphSize + 1));
memset(pathNode, 0, sizeof(int) * (graphSize + 1));
pathNode[pathNodeSize++] = 1;
dfs(graph, graphSize, 1, graphColSize, &pathNodeSize, pathNode, allPath, &pathSize, eachPathSize);
// 输出
if (pathSize == 0) {
printf("-1\n");
return 0;
}
printRes(allPath, pathSize, eachPathSize);
return 0;
}
今日收获
- 图的存储方式:邻接矩阵、邻接表
- DFS深搜三部曲:确认递归函数,参数;确认终止条件;处理目前搜索节点出发的路径
- BFS
- 广搜的搜索方式就适合于解决两个点之间的最短路径问题。因为广搜是从起点出发,以起始点为中心一圈一圈进行搜索,一旦遇到终点,记录之前走过的节点就是一条最短路。