Input
The first line of the input file contains one integer N --- number of nodes in the tree (0 < N <= 10000). Next N-1 lines contain N-1 edges of that tree --- Each line contains a pair (u, v) means there is an edge between node u and node v (1 <= u,v <= N).
Output
Print the length of the longest path on one line.
Example
Input:
3
1 2
2 3
Output:
2
https://www.spoj.pl/problems/PT07Z/
public class LongestPathInATree
{
Lista[] vertices;
public static void main( String args[] ) throws Exception
{
new LongestPathInATree().resolver();
}
public LongestPathInATree()
{
// Vector de listas, donde se almacenaran las aristas
// para cada vertice
vertices = new Lista[ 10001 ];
for( int i = 1; i < vertices.length; i ++ )
vertices[ i ] = new Lista();
}
public void resolver( ) throws Exception
{
int numNodos = sig();
int orig, dest;
/**
* Representaremos el arbol como un vector de listas enlazadas,
* algo similar a como se representan los grafos en memoria.
*/
for( int i = 1; i < numNodos; i ++ )
{
orig = sig();
dest = sig();
// Como las aristas son sin direccion, tenemos que anadir
// 2 veces cada arista
vertices[ orig ].anadir( dest );
vertices[ dest ].anadir( orig );
}
Nodo act = vertices[ 1 ].cab.siguiente;
int nivelSubArbol1 = 0, nivelSubArbol2 = 0;
int temp;
/*
* Como el arbol es libre, podemos tomar como raiz cualquier vertice,
* en nuestro caso tomamos como raiz el vertice 1.
*
* La longitud maxima entre 2 nodos del arbol, es equivalente a
* la suma de los 2 mayores niveles de los subarboles de la raiz 1.
*
* Donde el nivel de un arbol, es igual a la longitud del camino mas
* largo entre su raiz y una de sus hojas.
*/
for( ; act != null; act = act.siguiente )
{
// Hallamos el nivel de cada subarbol de la raiz 1, y almacenamos
// los 2 mayores niveles.
temp = nivelSubArbol( 1, act.vertice, 1 );
if( temp > nivelSubArbol1 )
{
nivelSubArbol2 = nivelSubArbol1;
nivelSubArbol1 = temp;
}
else if( temp > nivelSubArbol2 )
{
nivelSubArbol2 = temp;
}
}
System.out.println( nivelSubArbol1 + nivelSubArbol2 );
}
public int nivelSubArbol( int padre, int vertice, int longCamino )
{
Nodo hijo = vertices[ vertice ].cab.siguiente;
// Si solo existe un hijo, eso indica que solo hay una arista,
// que es la que lo une con su padre, esta no se debe procesar.
if( hijo.siguiente == null )
return longCamino;
int nivelMaximoSubArbol = 0, temp;
// Calculamos el nivel para cada subarbol del nodo actual,
for( ; hijo != null; hijo = hijo.siguiente )
{
// Verificamos que no estemos procesando al padre el vertice
if( hijo.vertice != padre )
{
// Calculamos el nivel maximo de este subarbol, aplicando
// recursivamente el mismo procesidiento para cada uno
// de sus subarboles
temp = nivelSubArbol( vertice, hijo.vertice, longCamino + 1 );
if( temp > nivelMaximoSubArbol )
nivelMaximoSubArbol = temp;
}
}
return nivelMaximoSubArbol;
}
class Nodo
{
int vertice;
Nodo siguiente;
Nodo( int vert )
{
vertice = vert;
}
}
class Lista
{
Nodo ult = new Nodo( 0 );
Nodo cab = ult;
void anadir( int val )
{
ult.siguiente = new Nodo( val );
ult = ult.siguiente;
}
}
public static int sig() throws Exception
{
int val = 0;
int car = System.in.read();
while( car > 47 && car < 58 )
{
val = 10 * val + car - 48;
car = System.in.read();
}
return val;
}
}
disculpa quisiera saber más o menos por qué tu solución es correcta si tomo las maximas alturas de cada rama y sumo solo la maxima y la casi maxima, no dan ciertos casos de la pagina, creo que el problem setter ha cambiado la test data.
ResponderEliminar