← Все вопросы

Как найти длину кратчайшего/длиннейшего пути в DAG через ДП по топологической сортировке?

Задан 18 месяцев назад1.2к просмотров2 ответа
9

Дан ориентированный ациклический граф (DAG) с весами рёбер. Нужно найти длиннейший путь из вершины-источника (или вообще длиннейший путь в графе). Для общих графов длиннейший путь NP-труден, но для DAG, говорят, решается ДП. Как именно и почему здесь работает?

2 ответа

14
✓ Принятый ответ — помог автору

В DAG нет циклов, поэтому вершины можно упорядочить топологически: каждое ребро ведёт «вперёд» по порядку. Тогда dp[v] (длиннейший путь, заканчивающийся в v) зависит только от уже обработанных предшественников — никакой циклической зависимости, ДП корректно.

int n;
vector<vector<pair<int,long long>>> g; // g[u] = {(v, weight), ...}
vector<int> order;          // топологическая сортировка (Kahn или DFS)
vector<long long> dp(n, 0); // dp[v] = длиннейший путь, кончающийся в v

for (int u : order)                 // в топологическом порядке
  for (auto [v, w] : g[u])
    dp[v] = max(dp[v], dp[u] + w);  // релаксация вперёд

long long ans = *max_element(dp.begin(), dp.end());

Для кратчайшего пути — то же самое, но dp инициализируем INF (источник = 0) и берём min. Это работает даже с отрицательными весами (в отличие от Дейкстры), потому что топопорядок гарантирует, что dp[u] финализирован до релаксации u → v.

Сложность $O(V + E)$ — линейно, и топосортировка, и проход по рёбрам. Для длиннейшего пути long long, чтобы не переполнить при больших весах.

6

Почему это и есть «ДП на DAG» в общем виде: любая корректная мемоизация задаёт DAG зависимостей подзадач. Состояния — вершины, «переход A зависит от B» — ребро. Раз зависимости ациклические, существует топопорядок, в котором их можно вычислять итеративно. Поэтому фраза «перейти от рекурсии с мемоизацией к итеративному ДП» = «обойти граф зависимостей в топологическом порядке».

Частая ошибка: пытаться применить эту схему к графу с циклами — тогда топосортировки нет (Kahn не вытолкнет все вершины), и длиннейший путь становится NP-трудным. Перед ДП убедись, что граф реально ациклический.

Ваш ответ

Войдите, чтобы ответить на вопрос.