第七章(11).每对顶点间的最短路径

来源:互联网 发布:淘宝500的充气娃娃图片 编辑:程序博客网 时间:2024/06/15 23:25

#include < stdio.h >
#include < stdlib.h >
#include < string.h >
#include < limits.h >

#define TRUE 1  
#define FALSE 0    
#define OK 1
#define ERROR 0
#define OVERFLOW -2     

typedef int Status ;

//---------------图的数组(邻接矩阵)存储表示------------------//

#define INFINITY INT_MAX    //最大值(无穷大)INT_MAX = 2147483647
#define MAX_VERTEX_NUM 20    //最大顶点个数(vertex顶点)
#define MAX_INFO 20      //关于边的信息的字符串长度
#define MAX_NAME 5      //关于顶点信息的字符串长度

typedef int VRType ;     
typedef char InfoType ;
typedef char VertexType[MAX_NAME] ;  //VertexType可以根据实际情况灵活设定类型!int,float,char…

typedef struct ArcCell //此例中,VRType为权值,InfoType为描叙信息。
{
 VRType adj ;  //VRType是顶点关系类型。对于无权图,用1或0表示相邻否。对于带权图,则为权值类型。
 InfoType *info ; //该弧(Arc)相关的信息的指针
} ArcCell , AdjMatrix[ MAX_VERTEX_NUM ][ MAX_VERTEX_NUM ] ;

typedef struct
{
 VertexType vexs[ MAX_VERTEX_NUM ] ; //顶点向量
 AdjMatrix arcs ;     //邻接矩阵
 int vexnum , arcnum ;    //图的当前顶点数和弧树
}MGraph ;                                                                                               

Status InitGraph( MGraph *G ) ;
Status InputInformation( MGraph *G , int i , int j ) ;
Status LocateVex( MGraph G , VertexType u ) ;
Status CreateDG( MGraph *G ) ;
Status DestroyGraph( MGraph *G ) ;
Status Output( MGraph G ) ;

//--------------------------------------------------------------------------------//

typedef int PathMatrix[ MAX_VERTEX_NUM ][ MAX_VERTEX_NUM ][ MAX_VERTEX_NUM ] ;
typedef int DistancMatrix[ MAX_VERTEX_NUM ][ MAX_VERTEX_NUM ] ;

Status ShortestPath_FLOYD( MGraph G , PathMatrix *P , DistancMatrix *D ) ; //(*P)为一个三维对象,(*D)为一个二维对象


 

 

 

 

 

#include "head.h"

//--------------------Basic Fuction---------------------//

Status InitGraph( MGraph *G )
{
 int i , j ;
 
 printf( "Input the number of Vertex and Arc : " ) ;
 scanf( "%d %d" , &( *G ).vexnum , &( *G ).arcnum ) ;  
 
 printf("Input the vector of %d vex( %d char ): \n" , ( *G ).vexnum , MAX_NAME ) ;
 for( i = 0 ; i < ( *G ).vexnum ; ++ i )  //构造顶点向量  Input:a b c d …(输入字符处理)
 {
  scanf( "%s" , ( *G ).vexs[ i ] ) ;  //访存错误,因为无内存。刚开始定义typedef char* VertexType;  所以( *G ).vexs[ i ]只是一个没有空间的指针
 }       

 for( i = 0 ; i < ( *G ).vexnum ; ++ i )  
 {
  for( j = 0 ; j < ( *G ).vexnum ; ++ j )
  {   
   ( *G ).arcs[ i ][ j ].adj = INFINITY ;//刚开始,点与点的距离为无穷远.信息为无。
   ( *G ).arcs[ i ][ j ].info = NULL ; 
  }
 }

 return OK ;
}

Status InputInformation( MGraph *G , int i , int j )
{
 char s[ MAX_INFO ] , *info ;
 int w ;
 
 printf("请输入该边的相关信息(%d个字符): ", MAX_INFO ) ;
 gets( s );
 w = strlen( s ) ;
 if( w )
 {
  info = ( char * )malloc( ( w + 1 ) * sizeof( char ) ) ;
  strcpy( info , s ) ;
  ( *G ).arcs[ i ][ j ].info = info ;
 }
 return OK ;
}

Status LocateVex( MGraph G , VertexType u ) //若G中存在顶点u,则返回该顶点在图中位置;否则返回-1 
{
 int i ;
 
 for( i = 0 ; i < G.vexnum ; ++ i )
 {
  if( strcmp( u , G.vexs[ i ] ) == 0 )
   return i ;
 }
 return EOF ;   //EOF means -1 .
}

Status CreateDG( MGraph *G )  //构造有向图*G
{
 int IncInfo , adj ;
 int i , j , k ;
 VertexType va , vb ;
 
 InitGraph( G ) ;
 printf( "It's there any information for arc?( 1 means yes ): " ) ;
 scanf( "%d" , &IncInfo ) ;  
 printf( "请输入%d条弧的弧尾、弧头以及权值: \n" , ( *G ).arcnum ) ;

 for( k = 0 ; k < ( *G ).arcnum ; ++ k )  //构造邻接矩阵
 {
  scanf( "%s%s%d", va , vb , &adj ) ; 
  i = LocateVex( *G , va ) ;
  j = LocateVex( *G , vb ) ;
  ( *G ).arcs[ i ][ j ].adj = adj ;  //有向图,带权值
  
  if( IncInfo )       //若弧含有相关信息,则输入
  {
   InputInformation( G , i , j ) ; 
  }
 }   
 
 return OK ; 
}

//--------------------Other Fuction-------------------------//

Status DestroyGraph( MGraph *G )  //Destroy一般为释放申请的资源和初始化!
{
 int i , j ;
 
 for( i = 0 ; i < ( *G ).vexnum ; ++ i )
 {
  for( j = 0 ; j < ( *G ).vexnum ; ++ j )
  {   
   if( ( *G ).arcs[ i ][ j ].info && ( *G ).arcs[ i ][ j ].adj != INFINITY )
   {
    free( ( *G ).arcs[ i ][ j ].info ) ;
    ( *G ).arcs[ i ][ j ].info = NULL ;
   }
  }
 }

 ( *G ).arcnum = 0 ;
 ( *G ).vexnum = 0 ;
 return OK ;
}

Status Output( MGraph G )
{
 int i , j , infor = 0 ;
 char s[ 7 ] , sa[ 4 ] ;

 strcpy( s , "有向网" ) ;
 strcpy( sa , "弧" ) ;

 printf( "\n输出含有%d顶点和%d条%s的%s:" , G.vexnum , G.arcnum , sa , s ) ;

 printf( "\nOutput the vexs:\n" ) ;
 for( i = 0 ; i < G.vexnum ; ++ i )
 {
  printf( "G.vexs[ %d ] = " , i ) ;
  puts( G.vexs[ i ] ) ;   //根据VertexType而变化
 }

 printf( "\nOutput the adj:\n" ) ;
 for( i = 0 ; i < G.vexnum ; ++ i )
 {
  for( j = 0 ; j < G.vexnum ; ++ j )
   printf( "%15d" , G.arcs[ i ][ j ].adj ) ;
  printf( "\n" ) ;
 }

 for( i = 0 ; i < G.vexnum ; ++ i )
 {
  for( j = 0 ; j < G.vexnum ; ++ j )
  {
   if( G.arcs[ i ][ j ].info )
   {
    infor = 1 ;
    break ;
   }
  }
  if( infor )
   break ;
 }

 if( infor )
 {
  printf( "\nOutput the info:\n" ) ;
  printf( "Vex1(弧尾) Vex2(弧头) 该%s信息:\n" , sa ) ;

  for( i = 0 ; i < G.vexnum ; ++ i )
  {
   for( j = 0 ; j < G.vexnum ; ++ j )
   {
    if( G.arcs[ i ][ j ].info )
    {
     printf( "%5s %11s     %s\n" , G.vexs[ i ] , G.vexs[ j ] , G.arcs[ i ][ j ].info ) ;
    }
   }
  }
 } 
 else
 {
  printf( "There is't any information!\n" ) ;
 }

 return OK ;
}

//-----------------------------------------------------------------------------------//

//用Floryd算法求有向网G中各对顶点v和w之间的最短路径P[v][w]及其带权长度D[v][w],若P[v][w][u]为TRUE,则u是从v到w当前求得最短路径上的顶点.

Status ShortestPath_FLOYD( MGraph G , PathMatrix *P , DistancMatrix *D )
{
 int v , w , u , i ;

 for( v = 0 ; v < G.vexnum ; ++ v )  //求各对结点之间初始化已知路径及距离
 {
  for( w = 0 ; w < G.vexnum ; ++ w )
  {
   (*D)[ v ][ w ] = G.arcs[ v ][ w ].adj ;
   for( u = 0 ; u < G.vexnum ; ++ u )
    (*P)[ v ][ w ][ u ] = TRUE ;

   if( (*D)[ v ][ w ] < INFINITY ) //从v到w有直接路径
   {
    (*P)[ v ][ w ][ v ] = TRUE ;
    (*P)[ v ][ w ][ w ] = TRUE ;
   }
  }
 }

 for( u = 0 ; u < G.vexnum ; ++ u )
 {
  for( v = 0 ; v < G.vexnum ; ++ v )
  {
   for( w = 0 ; w < G.vexnum ; ++ w )
   {
    if( (*D)[ v ][ u ] + (*D)[ u ][ w ] < (*D)[ v ][ w ] ) //从v经u到w的一条路径更短
    {
     (*D)[ v ][ w ] = (*D)[ v ][ u ] + (*D)[ u ][ w ] ;

     for( i = 0 ; i < G.vexnum ; ++ i )
      (*P)[ v ][ w ][ i ] = (*P)[ v ][ u ][ i ] || (*P)[ u ][ w ][ i ] ;
    }
   }
  }
 }
 return OK ;
}

int main( )
{
 MGraph G ;
 int i , j , k ;
 PathMatrix P ;
 DistancMatrix D ;

 CreateDG( &G ) ;
// Output( G ) ;

 for( i = 0 ; i < G.vexnum ; ++ i )
 {
  G.arcs[ i ][ i ].adj = 0 ;   //首先,一个顶点到自己的距离应是0.
 }
 
 printf( "Output the Matrix:\n" ) ;//输出邻接矩阵
 for( i = 0 ; i < G.vexnum ; ++ i )
 {
  for( j = 0 ; j < G.vexnum ; ++ j )
   printf( "%12d" , G.arcs[ i ][ j ].adj ) ;
  printf( "\n" ) ;
 }

 ShortestPath_FLOYD( G , &P , &D ) ;  //求最短路径
 
 printf( "Output the Shortest Path:\n" ) ;//输出最短路径长度
 for( i = 0 ; i < G.vexnum ; ++ i )
 {
  for( j = 0 ; j < G.vexnum ; ++ j )
   printf( "%s ----> %s : %3d\n" , G.vexs[ i ] , G.vexs[ j ] , D[ i ][ j ] ) ;
  printf( "\n" ) ;
 }

 //输出最短路径上的所有点
 printf( "Ouput the Way:\n" ) ;
 for( i = 0 ; i < G.vexnum ; ++ i )
 {
  for( j = 0 ; j < G.vexnum ; ++ j )
  {
   if( i != j )
   {
    printf( "%s  " ,  G.vexs[ i ] ) ;
    for( k = 0 ; k < G.vexnum ; ++ k )
    {
     if( k != i && k != j && P[ i ][ j ][ k ] == TRUE &&  ( D[ i ][ j ] >= D[ i ][ k ] + D[ k ][ j ] ) )  //注意"=".我太强大了!呵呵……
      printf( "%s  " ,  G.vexs[ k ] ) ;
    }
    printf( "%s\n" ,  G.vexs[ j ] ) ;
   }
   else  
    printf( "The distance to self is 0!\n" ) ;   
  }
  printf( "\n" ) ;
 }

 return 0 ;
}


0 0
原创粉丝点击