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;
}
相关推荐
Death20026 分钟前
Qt 6 相比 Qt 5 的主要提升与更新
开发语言·c++·qt·交互·数据可视化
reyas1 小时前
B树系列解析
数据结构·b树
Indigo_code2 小时前
【数据结构】【顺序表算法】 删除特定值
数据结构·算法
麻辣韭菜2 小时前
网络基础 【HTTP】
网络·c++·http
阿史大杯茶3 小时前
Codeforces Round 976 (Div. 2 ABCDE题)视频讲解
数据结构·c++·算法
LluckyYH3 小时前
代码随想录Day 58|拓扑排序、dijkstra算法精讲,题目:软件构建、参加科学大会
算法·深度优先·动态规划·软件构建·图论·dfs
转调3 小时前
每日一练:地下城游戏
开发语言·c++·算法·leetcode
不穿格子衬衫4 小时前
常用排序算法(下)
c语言·开发语言·数据结构·算法·排序算法·八大排序
wdxylb4 小时前
使用C++的OpenSSL 库实现 AES 加密和解密文件
开发语言·c++·算法
aqua35357423584 小时前
蓝桥杯-财务管理
java·c语言·数据结构·算法