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