LOJ #2793. 「CCO 2015」路短最

本文深入探讨了在一个有向图中寻找从起点到终点的最长路径问题。通过使用记忆化搜索算法,文章详细解释了如何避免重复计算,提高效率。特别关注了如何利用位运算检查路径集合,确保每个点仅被访问一次,从而找到从000点到n-1点的最长路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:传送门

0 0 0点走到 n − 1 n-1 n1点,每个点最多走一次,求最长路径
f [ i ] [ S ] f[i][S] f[i][S]表示当前在 i i i点,经过的路经集合为 S S S的最长路
由于每个点最多经过一次,所以转移很显然
如果下一个枚举到的点 v v v不在路径集合 S S S中,即!(S & (1<<v))
用记搜来实现

/**
 * @Date:   2019-10-19T16:56:21+08:00
 * @Last modified time: 2019-10-20T19:08:57+08:00
 */
#include <bits/stdc++.h>
#define A 1010

using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
struct node {int next, to, w;}e[A];
int head[A], num;
void add(int fr, int to, int w) {e[++num].next = head[fr]; e[num].to = to; e[num].w = w; head[fr] = num;}
int f[18][1 << 18], n, m, a, b, c;
int dfs(int fr, int S) {
    if (fr == n - 1) return 0;
    if (~f[fr][S]) return f[fr][S];
    int ans = -inf;
    for (int i = head[fr]; i; i = e[i].next) {
        int ca = e[i].to;
        if (!(S & (1 << ca)))
            ans = max(ans, e[i].w + dfs(ca, S | (1 << ca)));
    }
    return f[fr][S] = ans;
}

int main(int argc, char const *argv[]) {
    cin >> n >> m; memset(f, -1, sizeof f);
    for (int i = 1; i <= m; i++) cin >> a >> b >> c, add(a, b, c);
    cout << dfs(0, 1) << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

良月澪二

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值