首页 > 其他分享 >经典图论遍历问题:传递信息

经典图论遍历问题:传递信息

时间:2023-03-30 21:23:59浏览次数:31  
标签:图论 遍历 int graph 传递信息 vector relation 节点

小朋友 A 在和 ta 的小伙伴们玩传信息游戏,游戏规则如下:

有 n 名玩家,所有玩家编号分别为 0 ~ n - 1,其中小朋友 A 的编号为 0
每个玩家都有固定的若干个可传信息的其他玩家(也可能没有)。传信息的关系是单向的(比如 A 可以向 B 传信息,但 B 不能向 A 传信息)。
每轮信息必须需要传递给另一个人,且信息可重复经过同一个人
给定总玩家数 n,以及按 [玩家编号,对应可传递玩家编号] 关系组成的二维数组 relation。返回信息从小 A (编号 0 ) 经过 k 轮传递到编号为 n-1 的小伙伴处的方案数;若不能到达,返回 0。

示例 1:
输入:n = 5, relation = [[0,2],[2,1],[3,4],[2,3],[1,4],[2,0],[0,4]], k = 3
输出:3
解释:信息从小 A 编号 0 处开始,经 3 轮传递,到达编号 4。共有 3 种方案,分别是 0->2->0->4, 0->2->1->4, 0->2->3->4。

示例 2:
输入:n = 3, relation = [[0,2],[2,1]], k = 2
输出:0
解释:信息不能从小 A 处经过 2 轮传递到编号 2

限制:

  • 2 <= n <= 10
  • 1 <= k <= 5
  • 1 <= relation.length <= 90, 且 relation[i].length == 2
  • 0 <= relation[i][0],relation[i][1] < n 且 relation[i][0] != relation[i][1]

遍历问题可以用两种遍历方式实现

深度优先遍历:从起点开始遍历;
1.遍历当前节点 a
2.如果 a 能到达 b, 则开始遍历 b;对于 b, k = k - 1;
3.如果 b 能到达下一个节点,又开始遍历下一个节点; 对于该节点,k 又 在 b 的基础上减一
...
4.直到 k = 0,或者没有下一个节点时,返回上一个层的节点,继续遍历上一层节点

class Solution {
public:
    int res = 0;
    int target;
    void dfs(vector<vector<int>> &graph, int cur, int k) {
        if (k == 0)
            return;
        for (auto to : graph[cur]) {
            if (to == target && k == 1) {
                res++;
            }
            dfs(graph, to, k - 1);
        }
    }
    int numWays(int n, vector<vector<int>>& relation, int k) {
        vector<vector<int>> graph(n);
        for (const auto &edge : relation) {
            graph[edge[0]].push_back(edge[1]);
        }

        target = n - 1;
        dfs(graph, 0, k);
        return res;
    }
};

广度优先遍历:从起点开始遍历
1.遍历起点能到达的所有节点,加到队列中。队列中保存了第一轮能到达的所有节点
2.遍历队列中的所有节点,对于能到达的节点又加入到队列中,同时把第一轮的节点移除。此时队列中保存了所有第二轮能到达的节点。
...
3.一直遍历 k 轮,此时队列中保存的是第 k 轮能到达的所有节点
4.对这些节点进行判断,判断是否等于 n - 1;

int numWays(int n, vector<vector<int>>& relation, int k) {
    vector<vector<int>> graph(n);
    for (const auto &edge : relation) {
        graph[edge[0]].push_back(edge[1]);
    }

    queue<int>q;
    q.push(0);
    while (k--) {
        int size = q.size();
        for (int i = 0; i < size; i++) {
            int cur = q.front();
            q.pop();
            for (auto to : graph[cur]) {
                q.push(to);
            }
        }
    }
    int res = 0;
    while (!q.empty()) {
        if (q.front() == n - 1) {
            ++res;
        }
        q.pop();
    }
    return res;
}

该问题可以由小问题的结果推导出大问题的结果,也可以用动态规划实现
dp[i][j] 表示经过 i 轮,能到达节点 j 的方案数量。

int numWays(int n, vector<vector<int>>& relation, int k) {
    vector<vector<int>> dp(k + 1, vector<int>(n));
    dp[0][0] = 1;
    for (int i = 1; i <= k; i++) {
        for (const auto &edge : relation) {
            dp[i][edge[1]] += dp[i - 1][edge[0]];
        }
    }
    return dp[k][n - 1];
}

标签:图论,遍历,int,graph,传递信息,vector,relation,节点
From: https://www.cnblogs.com/AngleLin/p/17274343.html

相关文章

  • 读取数据库返回 ResultSet的时候,遍历数据用while (rs.next())数据量大的时候很慢。
    在做中台数据的时候,需要同步其他部位的系统的数据,目前同步数据要和其他部位的数据库对接,对方数据库为Oracle在读取的过程中,数据量比较大,已经做了分页处理,分页大小为1000行......
  • [shell] 读取多行输出到数组/遍历awk输出的某一行
    效果想要达到的效果为,使用awk切分输出后,遍历每一行的输出。以下以ls-lh命令示例,遍历输出ls-lh命令的第一列输出。实际使用替换ls-lh演示1.存放到数组后遍历数组第......
  • 2023-03-29 图的深度优先遍历
    图的深度优先遍历1数据结构遍历的意义每种数据结构,都必须有遍历的方式很多算法的本质都是遍历,对于图论问题,真正理解遍历,已经可以应付80%的问题了树的遍历复习复......
  • CF(2E) Keshi in Search of AmShZ (图论,最短路,建边权值变形)
      思路: 关键是操作2的性质:随机找->找一个路径最长的点操作1,阻止建边顾名思义, 发现和最短路很想,从n到每一个点的权值嘛改变权值更新方式,边的权值为:va......
  • 链表的遍历
    练习1:一组整数已存放在带头结点的单链表中,设计算法,求结点值小于结点平均值的结点个数,并通过函数值返回结果。 #include<stdio.h>#include<stdlib.h>typedefstructnode{......
  • libx11遍历窗体上所有组件
    libx11遍历窗体上所有组件ANSWER想要遍历窗体上的所有组件,需要先获取窗体的ID,然后通过XQueryTree函数来获取窗体的子组件ID列表。可以通过以下步骤来实现:获取窗体I......
  • ]Java中HashMap遍历的两种方式
    笔试的时候,两次都要用到工具类hashmap,这个东西用起来果然爽啊,但是在我遍历这个map的时候,迭代器写不出来了,真是悲催了,于是还是找下吧,下面的可是要记住用处啊Java中HashM......
  • 二叉树(建树|遍历|寻找最大最小深度)
    二叉树基础操作1.实现思路建树:递归从数组中按照层级建立递归:提供6种建树操作(前、中、后序递归和非递归)最大深度:利用回溯|递归实现两种操作最小深度:利用递归实现2.代......
  • HashMap和LinkedHashMap遍历机制
    原文链接:HashMap和LinkedHashMap遍历机制对HashMap和LinkedHashMap遍历的几种方法以HashMap为例,LinkedHashMap方法一样。一共有三种遍历方式Iterator<Map.Entry......
  • 图论--网络流最大流问题
    问题表述:给定一幅图(n个结点,m条边),每一条边有一个容量,现在需要将一些物品从结点s(称为源点)运送到结点t(称为汇点),可以从其他结点中转,求最大的运送量。在介绍最大流问题的解决方法......