// vector<vector<pair<int, int>> edges - ребра. edges[i][j] j-ое ребро из вершины i. first - конец ребра, second - длина ребра.
// heights - массив для ответа.
// was - массив для пометок о пройденных вершинах
bool Dfs(int v, int height, const vector<vector<pair<int, int>> &edges, int heights[], bool was[]) {
was[v] = true;
heights[v] = height;
for (const auto &edge : edges[v]) {
int end = edge.first;
int expected_height = height + edge.second;
if (was[end]) {
// Конец уже обработан. Проверить на конфликт в этом ребре.
if (heights[end] != expected_height)
return false;
} else {
// Конец не обработан, обрабатываем
if (!Dfs(end, expected_height, edges, heights, was))
return false;
}
}
return true;
}
...
// как вызывать dfs
was[] <- заполнить false для всех вершин
bool good = true;
for (i = 0; i < n; ++i) {
// вершина была обработана предыдущим обходом.
if (was[i])
continue;
if (!Dfs(i, 0, edges, heights, was)) {
good = false;
break;
}
}
// тут heights[] уже заполнен правильно, если good == true, иначе - в графе неустранимый конфликт.
Что-то вроде этого должно работать:
Потом можно общаться к dp[i][j]. Массив a можно сделать глобальным, или просто передавать в функцию - это копий лишних делать не будет.