Bellman‐Fordアルゴリズム単一ソース最短経路(o(nm))


解決した問題は依然としてA都市からB都市への最短経路を見つけることである.
Bellman-Fordアルゴリズムは、各頂点間の最短経路を探し出し、経路重み値は負数であってもよいが、負重み回路(この回路に負重み経路が存在する)は存在しない.Dijkstraアルゴリズムは、ある頂点から他の頂点への最短経路を探し出す.もちろんDijkstraは各頂点間の最短経路を探し出し、n回Dijkstraをすればよい.
構想:各ペアの頂点i,jに対して,iからjへの最短経路の重みを絶えず縮小する.i,jに頂点kを加え、iからk,kからjまでの経路の和がiからjまでの経路長より小さいか否かを判断し、kを加えた場合、iからjまでの経路長を調整する.
縮小の条件:a[i][j]>a[i][k]+a[k][j];(a:頂点ペアあたりのパス長)
次の2組のテスト配列は,前のグループが負の重み回路を構成しておらず,後のグループが負の重み回路であり,正確な結果が得られない.
第1グループ:
5 1 2 6 2 3 5 3 2 -2 5 3 -3 4 3 7 2 4 -4 5 4 9 1 5 7 4 1 2 2 5 8 0 0 0
2番目のグループ:
3 1 2 2 2 3 3 3 1 -8 0 0 0
 

#include<stdio.h>
#define MAX 10000
 
/* */
int a[ 100 ] [ 100 ] ;
/* */
int path[ 100 ] [ 100 ] ;
/* */
int c[ 100 ] [ 100 ] ;
 
void Floyd( int n)
{
int i,j,k;
/* a,path*/
for ( i= 1 ; i<= n; ++ i)
{
for ( j= 1 ; j<= n; ++ j)
{
if ( c[ i] [ j] ! = MAX)
{
path[ i] [ j] = j;
}
else
{
path[ i] [ j] = - 1 ;
}
a[ i] [ j] = c[ i] [ j] ;
}
}
/* k i j p */
for ( k= 1 ; k<= n; ++ k)
{
for ( i= 1 ; i<= n; ++ i)
{
for ( j= 1 ; j<= n; ++ j)
{
if ( a[ i] [ j] > a[ i] [ k] + a[ k] [ j] )
{
/* */
a[ i] [ j] = a[ i] [ k] + a[ k] [ j] ;
/* */
path[ i] [ j] = path[ i] [ k] ;
}
}
}
}
}
 
/* */
int isNegationLoop( int n)
{
int i,j,k;
for ( k= 1 ; k<= n; ++ k)
{
for ( i= 1 ; i<= n; ++ i)
{
for ( j= 1 ; j<= n; ++ j)
{
/* k, i j , */
if ( a[ i] [ j] > a[ i] [ k] + a[ k] [ j] )
{
return 0 ;
}
}
}
}
return 1 ;
}
 
/* */
void Print( int n)
{
int i,j,next;
for ( i= 1 ; i<= n; ++ i)
{
for ( j= 1 ; j<= n; ++ j)
{
/*naxt path */
next= path[ i] [ j] ;
if ( next== - 1 )
{
printf ( "%d - %d no path/n " ,i,j) ;
}
else
{
/* i、j */
printf ( "%d " ,a[ i] [ j] ) ;
printf ( "%d " ,i) ;
while ( next! = j)
{
printf ( "-> %d " ,next) ;
/* */
next= path[ next] [ j] ;
}
printf ( "-> %d/n " ,j) ;
}
}
}
}
 
int main( )
{
int n,i,j,x,y,value;
scanf ( "%d" ,& n) ;
/* c*/
for ( i= 0 ; i<= n; ++ i)
{
for ( j= 0 ; j<= n; ++ j)
{
if ( i== j)
{
c[ i] [ j] = 0 ;
}
else
{
c[ i] [ j] = MAX;
}
}
}
while ( 1 )
{
/* */
scanf ( "%d%d%d" ,& x,& y,& value) ;
if ( x== 0 && y== 0 && value== 0 )
{
break ;
}
c[ x] [ y] = value;
}
Floyd( n) ;
if ( isNegationLoop( n) )
{
Print( n) ;
}
else
{
printf ( "the short loop isn't exit/n " ) ;
}
system ( "pause" ) ;
return 0 ;
}