import java.util.*;
public class BBShortest
{
static class HeapNode implements Comparable//最小堆结点表示
{
int i; // vertex number
float length;// current length
HeapNode(int ii, float ll)
{
i = ii;
length = ll;
}
public int compareTo(Object x)
{
float xl = ((HeapNode)x).length;
if (length < xl) return -1;
if (length == xl) return 0;
return 1;
}
}
public static void shortest(int v, float []dist, int []p ,int [][] a)
{//求最短路径
int n = p.length-1;
BinaryHeap heap = new BinaryHeap();
HeapNode enode = new HeapNode(v,0);
for (int j = 1; j <=n;j++)
dist[j] = Float.MAX_VALUE;
dist[v] = 0;
while(true)
{
for(int j = 1; j <= n; j++)
if(a[enode.i][j] < Float.MAX_VALUE&& enode.length + a[enode.i][j] < dist[j])
{
dist[j] = enode.length + a[enode.i][j];
p[j] = enode.i;
HeapNode node = new HeapNode(j,dist[j]);
heap.insert(node);
}
if(heap.isEmpty())break;
else enode = (HeapNode)heap.deleteMin();
}
}
public static void main(String[] args)//对给定的有向图,测试最短路径
{ int [][] a = new int[6][6];
for(int i = 1;i <6;i++)
for(int j = 1;j<6;j++)
a[i][j] = Integer.MAX_VALUE;
a[1][2] = 10;a[2][3] = 50;a[1][5]=100;a[1][4]=30;
a[3][5] = 10;a[4][3]=20;a[4][5]=60;
float [] d = {0,0,0,0,0,0};
int [] p = {0,0,0,0,0,0};
shortest(1,d,p,a);
for(int i = 0;i < d.length;i++)
System.out.println(d[i]);
for(int i = 0;i<p.length;i++)
System.out.println(p[i]);
}
}
class UnderflowException extends RuntimeException
{
/**
* Construct this exception object.
* @param message the error message.
*/
public UnderflowException( String message )
{
super( message );
}
}
interface PriorityQueue//建立优先级队列接口
{
/**
* The Position interface represents a type that can
* be used for the decreaseKey operation.
*/
public interface Position
{
/**
* Returns the value stored at this position.
* @return the value stored at this position.
*/
Comparable getValue( );
}
/**
* Insert into the priority queue, maintaining heap order.
* Duplicates are allowed.
* @param x the item to insert.
* @return may return a Position useful for decreaseKey.
*/
Position insert( Comparable x );
/**
* Find the smallest item in the priority queue.
* @return the smallest item.
* @throws UnderflowException if empty.
*/
Comparable findMin( );
/**
* Remove the smallest item from the priority queue.
* @return the smallest item.
* @throws UnderflowException if empty.
*/
Comparable deleteMin( );
/**
* Test if the priority queue is logically empty.
* @return true if empty, false otherwise.
*/
boolean isEmpty( );
/**
* Make the priority queue logically empty.
*/
void makeEmpty( );
/**
* Returns the size.
* @return current size.
*/
int size( );
void decreaseKey( Position p, Comparable newVal );
}
class BinaryHeap implements PriorityQueue//实现最小堆,实现优先队列接口
{
/**
* Construct the binary heap.
*/
public BinaryHeap( )
{
currentSize = 0;
array = new Comparable[ DEFAULT_CAPACITY + 1 ];
}
/**
* Construct the binary heap from an array.
* @param items the inital items in the binary heap.
*/
public BinaryHeap( Comparable [ ] items )
{
currentSize = items.length;
array = new Comparable[ items.length + 1 ];
for( int i = 0; i < items.length; i++ )
array[ i + 1 ] = items[ i ];
buildHeap( );
}
private void doubleArray()
{
Comparable [] tmp;
tmp= new Comparable[array.length];
for (int i=0;i<array.length;i++ )
{
tmp[i]=array[i];
}
array= new Comparable[2*tmp.length];
for (int i=0;i<tmp.length;i++ )
{
array[i]=tmp[i];
}
}
/**
* Insert into the priority queue.
* Duplicates are allowed.
* @param x the item to insert.
* @return null, signifying that decreaseKey cannot be used.
*/
public PriorityQueue.Position insert( Comparable x )
{
if( currentSize + 1 == array.length )
doubleArray();
// Percolate up
int hole = ++currentSize;
array[ 0 ] = x;
for( ; x.compareTo( array[ hole / 2 ] ) < 0; hole /= 2 )
array[ hole ] = array[ hole / 2 ];
array[ hole ] = x;
return null;
}
/**
* @throws UnsupportedOperationException because no Positions are returned
* by the insert method for BinaryHeap.
*/
public void decreaseKey( PriorityQueue.Position p, Comparable newVal )
{
throw new UnsupportedOperationException( "Cannot use decreaseKey for binary heap" );
}
/**
* Find the smallest item in the priority queue.
* @return the smallest item.
* @throws UnderflowException if empty.
*/
public Comparable findMin( )
{
if( isEmpty( ) )
throw new UnderflowException( "Empty binary heap" );
return array[ 1 ];
}
/**
* Remove the smallest item from the priority queue.
* @return the smallest item.
* @throws UnderflowException if empty.
*/
public Comparable deleteMin( )
{
Comparable minItem = findMin( );
array[ 1 ] = array[ currentSize-- ];
percolateDown( 1 );
return minItem;
}
/**
* Establish heap order property from an arbitrary
* arrangement of items. Runs in linear time.
*/
private void buildHeap( )
{
for( int i = currentSize / 2; i > 0; i-- )
percolateDown( i );
}
/**
* Test if the priority queue is logically empty.
* @return true if empty, false otherwise.
*/
public boolean isEmpty( )
{
return currentSize == 0;
}
/**
* Returns size.
* @return current size.
*/
public int size( )
{
return currentSize;
}
/**
* Make the priority queue logically empty.
*/
public void makeEmpty( )
{
currentSize = 0;
}
private static final int DEFAULT_CAPACITY = 100;
private int currentSize; // Number of elements in heap
private Comparable [ ] array; // The heap array
/**
* Internal method to percolate down in the heap.
* @param hole the index at which the percolate begins.
*/
private void percolateDown( int hole )
{
int child;
Comparable tmp = array[ hole ];
for( ; hole * 2 <= currentSize; hole = child )
{
child = hole * 2;
if( child != currentSize &&
array[ child + 1 ].compareTo( array[ child ] ) < 0 )
child++;
if( array[ child ].compareTo( tmp ) < 0 )
array[ hole ] = array[ child ];
else
break;
}
array[ hole ] = tmp;
}
}