Número de cruces en gráfico bipartito

En un gráfico bipartito, hay n nodos a la izquierda y m nodos a la derecha. Los nodos están ordenados de 1 a n y de 1 a m. Un nodo de la izquierda está conectado al nodo de la derecha. Todos los nodos no están conectados. Por ejemplo:

1 is connected to 4

2 is connected to 3

3 is connected to 2

3 is connected to 1

Quiero saber cuántos cruces hay en el gráfico (aquí 5 cruces). Un problema similar está allí en SPOJ

Quiero saber cómo se puede resolver este problema utilizando un árbol de índice binario como han mencionado algunos usuarios. Estoy resolviendo con algo O(n^2) y obteniendo TLE.

Esto no es una tarea. Ayer aprendí BIT y estaba buscando algunos problemas, así que encontré esto. Sólo dime el truco. Por favor, no escriba todo el programa.

preguntado el 22 de mayo de 12 a las 07:05

Debería volver a pensar en el dominio del problema. Los nodos del gráfico NO están ordenados, por lo que podría dibujar el gráfico de ejemplo anterior sin ningún cruce (dibuje sus dos columnas 3,1,2,4 y 1,2,4,3)). Por lo tanto, debe imponer alguna restricción geométrica sobre cómo se deben dibujar los nodos o solicitar el número mínimo de cruces (entonces debe corregir su ejemplo). -

2 Respuestas

Ordene los bordes por el índice del nodo izquierdo, luego (para índices iguales a la izquierda) por el índice del nodo derecho. Mire los índices de los nodos derechos. Cada cruce en el gráfico corresponde a un par de índices que no van en orden en esta lista ordenada. Solo necesita contar esos pares "no en orden".

Inserte secuencialmente cada índice del nodo derecho de la lista ordenada en el árbol de índice binario. Después de cada inserción, puede encontrar cuántos índices más grandes ya están en el árbol en tiempo O (log (m)). Entonces, la complejidad temporal de todo el algoritmo es O(h * (log(h) + log(m))): O(h * log(h)) para ordenar y O(h * log(m)) para calcular el número de inversiones de índice (aquí 'h' es el número de aristas). Puede mejorar esto a O(h * log(m)) usando la ordenación por radix o la ordenación por cubo.


Actualizar:

Como notó Android Decoded, el problema del número de inversiones se puede resolver usando un algoritmo divide y vencerás, basado en Merge Sort. Ver explicación detallada aquí. Este enfoque tiene una mayor complejidad de tiempo O(h * log(h)) que la complejidad de usar un árbol de índice binario O(h * log(m)), pero para gráficos dispersos, donde el número de aristas no es mucho mayor que el número de nodos, debería ser más rápido porque necesita menos memoria y es más compatible con la memoria caché.

La complejidad del enfoque Merge Sort puede mejorarse a O(h * log(m)) si eliminamos las entradas duplicadas durante la fusión. Para hacerlo, aplique Merge Sort a pares de (valor, número de instancias), donde los valores idénticos adyacentes se combinan en una entrada con el 'número de instancias' adecuado. En el peor de los casos, no se eliminan los duplicados para los primeros pases de combinación de log(m), esto tiene la complejidad de O(h * log(m)); luego quedan hasta log(n) pases cuando los duplicados se eliminan rápidamente en tiempo O(h).

Detalles de uso del árbol de índice binario:

Implemente un árbol de índice binario, que para una clave dada pueda devolver su índice en el árbol, comenzando desde el valor más grande (el más grande -> índice 0, el segundo más grande -> índice 1, ...). Luego, después de insertar cada elemento en el árbol, solicite su índice; ese sería el número de valores más grandes que se encuentran a la izquierda de este elemento en la lista ordenada.

Más detalles: Binary Index Tree puede implementarse como un árbol de búsqueda, cada nodo del cual se aumenta con el contador de nodos descendientes. No cree nodos separados para elementos duplicados, solo actualice los contadores de nodos descendientes para cada uno de ellos. Cuando se nos pregunte por el índice de alguna clave, primero debemos buscar un nodo, correspondiente a este índice en el árbol; entonces deberíamos sumar todos los contadores para el descendiente derecho inmediato de cada ancestro del nodo actual, incluido el descendiente derecho del propio nodo actual, pero excluyendo todos los casos en los que el nodo actual está a la derecha de algunos de sus ancestros.

contestado el 23 de mayo de 12 a las 10:05

Hmmm... Eso se ve genial... ¡Impresionante! Después de ordenar, este problema cambia a la cantidad de problemas de inversiones que se pueden resolver mediante Merge sort... asombroso... lo verificaré para otros casos de prueba... Gracias - dejavu

@AndroidDecoded: correcto, Merge Sort debería funcionar aquí mejor que Index Tree. - Evgeny Kluev

¿Puede explicar cómo podemos resolver el problema utilizando el árbol de índice binario? - dejavu

Si he entendido bien tu pregunta entonces

sabemos que podemos tener relaciones NpowerM (que este valor sea X) entre dos conjuntos si podemos encontrar un conjunto que no tenga intersecciones (digamos que lo encontramos como Y) entonces restamos el Y de X que es XY será la respuesta a su pregunta matemáticamente ... para encontrar la Y, ordena los elementos en el otro lado, digamos en el conjunto M y luego encuentre la subsecuencia creciente más larga ("http://en.wikipedia.org/wiki/Longest_increasing_subsequence") de N y M esto se puede hacer en O (nm) si eres lo suficientemente inteligente, entonces puedes hacerlo en O (NlogM) ... tiempo. para mayor claridad sobre la solución (existe un problema similar aquí "http://people.csail.mit.edu/bdean/6.046/dp/" haga clic en el enlace de construcción de puentes)

contestado el 22 de mayo de 12 a las 10:05

Si entendí bien tu respuesta, falla con este gráfico: {(1,3),(2,4),(3,1),(4,2)}. - Evgeny Kluev

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.