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;
}
相关推荐
嵌入式科普10 分钟前
十三、从0开始卷出一个新项目之瑞萨RZN2L串口DMA接收不定长
c语言·stm32·瑞萨·e2studio·rzn2l
_WndProc11 分钟前
C++ 日志输出
开发语言·c++·算法
薄荷故人_12 分钟前
从零开始的C++之旅——红黑树及其实现
数据结构·c++
m0_7482400213 分钟前
Chromium 中chrome.webRequest扩展接口定义c++
网络·c++·chrome
qq_4335545420 分钟前
C++ 面向对象编程:+号运算符重载,左移运算符重载
开发语言·c++
努力学习编程的伍大侠24 分钟前
基础排序算法
数据结构·c++·算法
TENET信条31 分钟前
代码随想录 day50 第十一章 图论part01
图论
XiaoLeisj1 小时前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
yuyanjingtao1 小时前
CCF-GESP 等级考试 2023年9月认证C++四级真题解析
c++·青少年编程·gesp·csp-j/s·编程等级考试