洛谷P5318 【深基18.例3】查找文献(c嘎嘎)

题目链接:P5318 【深基18.例3】查找文献 - 洛谷 | 计算机科学教育新生态

题目难度:普及---

题目描述:小 K 喜欢翻看洛谷博客获取知识。,每篇文章可能会有若干个(也有可能没有)参考文献的链接指向别的博客文章,帮助小 K 设计一种方法,使小 K 可以不重复、不遗漏的看完所有他能看到的文章,请对这个图分别进行 DFS 和 BFS,并输出遍历结果。如果有很多篇文章可以参阅,请先看编号较小的那篇(因此你可能需要先排序)。(如下图)

输入格式

共 m+1 行,第 1 行为 2 个数,n 和 m,分别表示一共有 n(n≤105) 篇文章(编号为 1 到 n)以及m(m≤106) 条参考文献引用关系。

输出格式

共 2 行。 第一行为 DFS 遍历结果,第二行为 BFS 遍历结果。

输入输出样例

解题思路 :本题很直接就是要你遍历一个图然后输出DFS和BFS后的结果,对于本题我们使用邻接表(不用邻接矩阵原因:n<1e5),本题要我们要排序,我们用vectoe来存每个节点所能到达的边然后从小到达排序。

DFS 和 BFS介绍:学过数据结构我们都知道DFS通俗来说是从图的一个点出发,选择下一个点再以下一个点向下选择直到你选择的点没有可以选择的点了,BFS,用通俗的话来说,就是你从图中的一个节点出发,其有几个子节点,你会先将这所有的子节点遍历,再挑其中的一个子节点,遍历它的所有子节点,再换到另外一个结点遍历其所有的子节点。这样一层层遍历,以此类推。

一些模板(常用邻接矩阵存储):

cpp 复制代码
// 对于每个点k,开一个单链表,存储k所有可以走到的点。h[k]存储这个单链表的头结点
int h[N], e[N], ne[N], idx;

// 添加一条边a->b
void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}

// 初始化
idx = 0;
memset(h, -1, sizeof h);
深度优先遍历:
cpp 复制代码
int dfs(int u)
{
    st[u] = true; // st[u] 表示点u已经被遍历过

    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!st[j]) dfs(j);
    }
}
  • 宽度优先遍历:
cpp 复制代码
queue<int> q;
st[1] = true; // 表示1号点已经被遍历过
q.push(1);

while (q.size())
{
    int t = q.front();
    q.pop();

    for (int i = h[t]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!st[j])
        {
            st[j] = true; // 表示点j已经被遍历过
            q.push(j);
        }
    }
}

最后奉上代码部分:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define _for(i, a, b) for (int i = (a); i < (b); i++)
#define _rep(i, a, b) for (int i = (a); i <= (b); i++)
typedef long long ll;
const int N = 100010;
vector<int>edge[N];
bool vis[N];
int n, m;

// 深度优先搜索
void dfs(int u) {//u指当前所在的节点
    vis[u] = true;//标记以避免重复访问
    cout << u << ' ';//输出 
    for (int i = 0; i<edge[u].size(); i ++) {
        int j = edge[u][i];
        if (!vis[j]) dfs(j);//递归到下一层 
    }
}

// 广度优先搜索
void bfs(int u) {
    queue<int> q;
    vis[u] = true;
    q.push(u);

    while (!q.empty()) {
        int t = q.front();
        cout << t << ' ';
        q.pop();//记得要弹出,否则会一直在第一层遍历

       for (int i = 0; i<edge[t].size(); i ++) {
            int j = edge[t][i];
            if (!vis[j]) {
                vis[j] = true;
                q.push(j);
            }
        }
    }
}

int read() { // 快读函数
    int k = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        k = k * 10 + ch - '0';
        ch = getchar();
    }
    return k * f;
}

int main() {
    // 读取 n 和 m
    n = read(), m = read();

    // 读取 m 条边
    while (m--) 
	{
        int x, y;
        x = read(), y = read();
        edge[x].push_back(y);      
    }
    for(int i=1; i<=n; i++) sort(edge[i].begin(),edge[i].end());//排序 
    
    dfs(1);
    cout<<endl;
    
    memset(vis, false, sizeof(vis));//记得一定要清空
    bfs(1);
    
    return 0;
}
相关推荐
希望我万事顺遂2 小时前
力扣hot100-滑动窗口最大值
数据结构·算法·leetcode
꧁细听勿语情꧂3 小时前
二叉树余题,排序、直接插入排序、希尔排序
c语言·开发语言·数据结构·算法
是main不是漫3 小时前
【双指针|LeetCode1089 复写零】巧用逆向思路,破解原地覆盖陷阱
数据结构·算法·leetcode
专注仿真13 小时前
知识问答模型用到的算法集详解及代码实例
python·算法·代码·大模型训练·控制算法
罗西的思考14 小时前
【轻量化复刻大模型 / KIMI K3】AttnRes 模块交互式演示
人工智能·算法·机器学习
好悬给我拽开线17 小时前
ZILOT 论文解析
算法
饮水桶_T19 小时前
JAVA IO流笔记
开发语言·数据结构·算法
星夜离尘5619 小时前
MATLAB 离散数据分箱:半开区间、末端点与计数、加权和、平均
算法·matlab
Pniubi19 小时前
力扣76.最小覆盖子串
算法·leetcode·职场和发展
地平线开发者20 小时前
征程6|用 hrt\_model\_exec 看清 YOLOv5x 的输入、原始输出和后处理
人工智能·算法