2024/2/12 图的基础知识 2

目录

查找文献

[P5318 【深基18.例3】查找文献 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)](#P5318 【深基18.例3】查找文献 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))

有向图的拓扑序列

[848. 有向图的拓扑序列 - AcWing题库](#848. 有向图的拓扑序列 - AcWing题库)

最大食物链计数

[P4017 最大食物链计数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)](#P4017 最大食物链计数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))


查找文献

P5318 【深基18.例3】查找文献 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这道题之前写过,但不太熟练,今天再来写一次

思路:要求输出dfs和bfs两种遍历情况

题目中说了要排序,所以先得把图中每个点先排序

dfs是深搜,搜到了没有遍历过的点就继续进入dfs,类似于递归

bfs是宽搜,建立一个int类型的队列,把没有搜到过的点全部入队并标记,由于循环是在队列里面进行的,所以函数不需要传参进去,最开始1文献入队就行了

完整代码:

cpp 复制代码
#include <bits/stdc++.h>
#define int long long
const int N = 2e5+10;
std::vector<std::vector<int>> g(N);
bool vis[N]{};
void dfs(int cur)
{
    std::cout<<cur<<" ";
    vis[cur]=true;
    for(int i = 0;i < g[cur].size();i ++)
    {
        if(vis[g[cur][i]]==false)
            dfs(g[cur][i]);
    }
}
void bfs()
{
    memset(vis,false,sizeof(vis));
    std::queue<int> q;
    q.push(1);
    vis[1]=true;
    while(!q.empty())
    {
        int cur=q.front();
        std::cout<<cur<<" ";
        q.pop();
        for(int i = 0;i < g[cur].size();i ++)
        {
            if(vis[g[cur][i]]==false)
            {
                vis[g[cur][i]]=true;
                q.push(g[cur][i]);
            }
        }
    }
}
signed main()
{
    int n,m;
    std::cin >> n >> m;
    for(int i = 1;i <= m;i ++)
    {
        int u,v;
        std::cin >> u >> v;
        g[u].push_back(v);
    }
    for(int i = 1;i <= n;i ++)
    {
        std::sort(g[i].begin(),g[i].end());
    }
    dfs(1);
    std::cout<<"\n";
    bfs();
    return 0;
}

有向图的拓扑序列

848. 有向图的拓扑序列 - AcWing题库

这道题是拓扑排序的模板题

拓扑图就是有向无环图

使用bfs进行广搜

1.选择一个入度为0的点,并进行输出

2.删掉这个点,并且删除后面所有的出边

3.重复步骤1和2,直到所有的点都被输出

完整代码:

cpp 复制代码
#include <bits/stdc++.h>
#define int long long
const int N = 2e5 + 10;
std::vector<std::vector<int>> g(N);
int d[N], ans[N];
int num = 0;
int n, m;
std::queue<int> q;
void bfs() {
    while (!q.empty()) {
        int cur = q.front();
        q.pop();
        ans[num++] = cur;
        for (int i = 0; i < g[cur].size(); i++) {
            d[g[cur][i]]--;
            if (d[g[cur][i]] == 0)
                q.push(g[cur][i]);
        }
    }
}
signed main() {
    std::cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int u, v;
        std::cin >> u >> v;
        g[u].push_back(v);
        d[v]++;
    }
    for (int i = 1; i <= n; i++) {
        if (!d[i]) {
           q.push(i);
        }
    }
    bfs();
    //std::cout<<num;
    if (num == n) {
        for (int i = 0; i < num; i++) {
            std::cout << ans[i] << " ";
        }
    } else
        std::cout << -1;
    return 0;
}

最大食物链计数

P4017 最大食物链计数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

食物链,只有捕食和被捕食的关系,不存在平级的关系,所以想到了拓扑排序

思路:

用二维vector存图,数组in和数组out分别存节点的入度数和出度数,再开一个f数组存路径,如果搜到了入度为0的(即食物链低端),就进入队列,每次搜索的时候节点的路径叠加,并且清空这个点的出度的边,再循环

最后遍历一遍,如果搜到了出度为0的点(即食物链顶端),那么答案加上这个数

记得取模

完整代码:

cpp 复制代码
#include <bits/stdc++.h>
#define int long long
const int N = 5e5+10;
const int mod = 80112002;
std::vector<std::vector<int>>g(N);
int in[N],out[N];//入度,出度
int f[N];//路径
std::queue<int> q;
void bfs()
{
    while(!q.empty())
    {
        int cur=q.front();
        q.pop();
        for(int i = 0;i < g[cur].size();i ++)
        {
            int next=g[cur][i];
            in[next]--;
            if(in[next]==0)
                q.push(next);
            f[next]=(f[next]+f[cur])%mod;
        }
    }
}
signed main()
{
    int n,m;
    std::cin >> n >> m;
    for(int i = 1;i <= m;i ++)
    {
        int u,v;
        std::cin >> u >> v;
        g[u].push_back(v);
        in[v]++;
        out[u]++;
    }
    for(int i = 1;i <= n;i ++)
    {
        if(in[i]==0)
        {
            q.push(i);
            f[i]=1;
        }
    }
    bfs();
    int ans=0;
    for(int i = 1;i <= n;i ++)
    {
        if(out[i]==0)
            ans=(ans+f[i])%mod;
    }
    std::cout<<ans;
    return 0;
}
相关推荐
yyt_cdeyyds几秒前
FIFO和LRU算法实现操作系统中主存管理
算法
暮色_年华2 分钟前
Modern Effective C++item 9:优先考虑别名声明而非typedef
c++
重生之我是数学王子10 分钟前
QT基础 编码问题 定时器 事件 绘图事件 keyPressEvent QT5.12.3环境 C++实现
开发语言·c++·qt
daiyang123...23 分钟前
测试岗位应该学什么
数据结构
alphaTao27 分钟前
LeetCode 每日一题 2024/11/18-2024/11/24
算法·leetcode
我们的五年34 分钟前
【Linux课程学习】:进程程序替换,execl,execv,execlp,execvp,execve,execle,execvpe函数
linux·c++·学习
kitesxian36 分钟前
Leetcode448. 找到所有数组中消失的数字(HOT100)+Leetcode139. 单词拆分(HOT100)
数据结构·算法·leetcode
做人不要太理性1 小时前
【C++】深入哈希表核心:从改造到封装,解锁 unordered_set 与 unordered_map 的终极奥义!
c++·哈希算法·散列表·unordered_map·unordered_set
程序员-King.1 小时前
2、桥接模式
c++·桥接模式
chnming19871 小时前
STL关联式容器之map
开发语言·c++