Cómo determinar si un DAG tiene una ruta con una longitud mayor que k

Este es un problema clásico de DP.

Introducción a DP para principiantes: la programación dinámica es una técnica en la que aceleramos el cálculo de una función recursiva que se puede dividir en subproblemas que se superponen (por ejemplo, la función de Fibonacci tiene muchos subproblemas superpuestos. Dibuje el árbol de recursión para fib (5) y verás cuántas veces aparecerá fib (3)). La forma de acelerar el cálculo implica almacenar subproblemas que ya se han calculado en una matriz de notas . De esta manera, cada vez que tengamos que calcular el mismo subproblema nuevamente, en lugar de bajar su árbol de recursión, simplemente devolvemos el valor almacenado en la matriz.

long long int memo [100];
largo largo int fib (int n)
{
if (memo [n] == -1) // aún no calculado
{
if (n == 0 || n == 1) memo [n] = 1;
else memo [n] = fib (n-1) + fib (n-2);
}
volver memo [n];
}

Ahora, para nuestro problema gráfico. Podemos definir la siguiente función recursiva para encontrar la ruta más pesada desde una fuente s hasta un destino t en un DAG:

Sea w [v] el peso del vértice v y h (v) el camino más pesado que comienza en el vértice v y termina en t, luego:

h (v) = w [v] si v == t

h (v) = max (w [v] + h (u) para cada u en adj [v]) de lo contrario

Podemos ver que esta función recursiva calculará algunos subproblemas muchas veces (superposición), por lo que podemos usar una matriz que almacenará los valores de h (v) ya calculados para evitar el recálculo:

int memo [MAX_NODES], w [MAX_NODES];
int s, t;

int h (int v)
{
if (v == t) devuelve w [v];
if (memo [v] == -1)
{
for (auto u: adj [v]) // cada u adyacente a v
memo [v] = max (memo [v], w [v] + h (u));
}
volver memo [v];
}

int main ()
{
// … lee tu entrada y construye el gráfico …
// … despeja la matriz de notas poniendo -1 en cada posición …
cout << "la ruta más pesada es" << h (s) << endl;
}

Como la función anterior encuentra la ruta más pesada que comienza en el vértice de origen, podemos verificar fácilmente si es mayor que k o no. El tiempo de ejecución de esta función es O (N + M). Dejaré la prueba como ejercicio 🙂

More Interesting

¿Cuáles son algunas de las estructuras de datos / algoritmos de clasificación más interesantes?

Algoritmos: ¿Qué sucede cuando un usuario crea una matriz de tamaño -100, qué sucede en la memoria?

Cómo comenzar a aprender y explorar el campo de los Algoritmos de Big Data

¿De qué maneras se usan los algoritmos y con qué frecuencia se usan?

Silicon Valley (serie de televisión): ¿Cuál es el ejemplo más cercano en la vida real al algoritmo de compresión de Pied Piper?

¿Es la incapacidad de implementar estructuras de datos básicas como una lista doblemente enlazada, un árbol con punteros primarios usando un código seguro la mayor debilidad de Rust?

¿Cómo se puede encontrar la complejidad del tiempo para el recorrido DFS?

¿La complejidad de los algoritmos de clasificación está relacionada con la cantidad de suposiciones que hago? ¿Por qué?

¿Cómo puedo encontrar la ruta más larga de un gráfico bidireccional utilizando el algoritmo BFS?

¿Hay algún campo de arranque en EE. UU. Que se centre en C ++ y algoritmos?

¿Hay algún buen algoritmo para clasificar los tonos de chino mandarín de un archivo de audio sin la necesidad de usar una red neuronal?

¿Cuál es un ejemplo de un algoritmo iterativo que se ejecuta en [matemáticas] O (2 ^ n) [/ matemáticas]?

¿Cuánto trabaja un analista de datos / científico de datos en un día? ¿Cuánto tiempo tienes para estudiar nuevos algoritmos y técnicas?

Cómo resolver este problema usando árboles de segmentos

¿Cuál es el punto de los algoritmos gráficos?