有向无环图从s出发到t的简单路径条数

本文深入探讨了深度优先搜索(DFS)和结合拓扑排序与动态规划(DP)的算法实现,通过具体代码示例展示了如何解决特定类型的路径计数问题。文章首先介绍了DFS的基本原理和应用,随后通过拓扑排序优化了路径搜索过程,并结合DP避免重复计算,最终高效求解从起点到终点的所有可能路径数量。
摘要由CSDN通过智能技术生成

文章目录

DFS

#include <iostream>
#include <vector>
using namespace std;
const int MAX_V = 101;
vector<int> map[MAX_V];
int book[MAX_V];
int st, ed;
int ans = 0;

void dfs(int s) {
    if (s == ed) {
        ans++;
        return;
    }
    for (auto i : map[s]) {
        if (!book[i]) {
            book[i] = 1;
            dfs(i);
            book[i] = 0;
        }
    }
}

int main() {
    int V, m;
    cin >> V >> m;
    cin >> st >> ed;
    while (m--) {
        int a, b;
        cin >> a >> b;
        map[a].push_back(b);
    }
    dfs(st);
    cout << ans;
}

拓扑排序+DP

#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int MAX_V = 101;
vector<int> map[MAX_V], a;
int book[MAX_V], deg[MAX_V], dp[MAX_V][MAX_V], e[MAX_V][MAX_V];
int st, ed, V, m;
int ans = 0, flags, flage;

void topo() {
    queue<int> q;
    for (int i = 1; i <= V; i++) {
        if (!deg[i]) {
            q.push(i);
        }
    }
    while (q.size()) {
        int tmp = q.front();
        q.pop();
        a.push_back(tmp);
        if (tmp == st)
            flags = a.end() - a.begin() - 1;
        if (tmp == ed)
            flage = a.end() - a.begin() - 1;
        for (auto i : map[tmp]) {
            deg[i]--;
            if (!deg[i])
                q.push(i);
        }
    }
}

int main() {
    cin >> V >> m;
    cin >> st >> ed;
    while (m--) {
        int a, b;
        cin >> a >> b;
        //存储边数
        e[a][b]++;
        map[a].push_back(b);
        //存储入度
        deg[b]++;
    }
    //topo的结果放在a中
    topo();
    for (int i = 1; i <= V; i++)
        dp[i][i] = 1;
    for (int i = flags + 1; i <= flage; i++) {
        for (int j = flags; j < i; j++) {
            if (e[a[j]][a[i]])
                //注意重边的情况
                dp[st][a[i]] += dp[st][a[j]] * e[a[j]][a[i]];
        }
    }
    cout << dp[st][ed];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值