洛谷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;
}
相关推荐
大千AI助手2 小时前
DTW模版匹配:弹性对齐的时间序列相似度度量算法
人工智能·算法·机器学习·数据挖掘·模版匹配·dtw模版匹配
YuTaoShao3 小时前
【LeetCode 热题 100】48. 旋转图像——转置+水平翻转
java·算法·leetcode·职场和发展
生态遥感监测笔记3 小时前
GEE利用已有土地利用数据选取样本点并进行分类
人工智能·算法·机器学习·分类·数据挖掘
Tony沈哲4 小时前
macOS 上为 Compose Desktop 构建跨架构图像处理 dylib:OpenCV + libraw + libheif 实践指南
opencv·算法
刘海东刘海东4 小时前
结构型智能科技的关键可行性——信息型智能向结构型智能的转变(修改提纲)
人工智能·算法·机器学习
pumpkin845145 小时前
Rust 调用 C 函数的 FFI
c语言·算法·rust
挺菜的5 小时前
【算法刷题记录(简单题)003】统计大写字母个数(java代码实现)
java·数据结构·算法
mit6.8245 小时前
7.6 优先队列| dijkstra | hash | rust
算法
2401_858286115 小时前
125.【C语言】数据结构之归并排序递归解法
c语言·开发语言·数据结构·算法·排序算法·归并排序