邻接表
#include <cstdio>
#include <vector>
using namespace std;
#define INF 0x7FFFFFFF
typedef struct
{ int w, adj; }Arcnode;
vector<vector<Arcnode>> G;
vector<int > Path, nPath, Dist;
bool check( int N )
{
bool flag = false;
for( int i = 0; i < N; ++i )
for( int j = 0; j < G[i].size(); ++j )
if( Dist[i] != INF && Dist[ G[i][j].adj ] > Dist[i] + G[i][j].w )
{
flag = true;
Dist[ G[i][j].adj ] = Dist[i] + G[i][j].w;
Path[ G[i][j].adj ] = i;
nPath[ G[i][j].adj ] = nPath[i];
}
else if( Dist[i] != INF && Dist[ G[i][j].adj ] == Dist[i] + G[i][j].w && i != Path[ G[i][j].adj ] )
nPath[ G[i][j].adj ] += nPath[i];
return flag;
}
bool BF( int N )
{
for( int i = 0; i < N - 1; ++i )
if( !check(N) )
return true;
return !check(N);
}
int main()
{
int N, M, V1, V2, a, b, w;
Arcnode temp;
scanf("%d %d %d %d", &N, &M, &V1, &V2);
Path.resize(N);
Dist.resize(N);
nPath.resize(N);
G.resize(N);
fill( Dist.begin(), Dist.end(), INF );
fill( Path.begin(), Path.end(), -1 );
Dist[V1] = 0;
nPath[V1] = 1;
for( int i = 0; i < M; ++i )
{
scanf("%d %d %d", &a, &temp.adj, &temp.w);
G[a].push_back( temp );
}
if( BF( N ) )
{
for( int i = 0; i < N; ++i )
printf("%d%s", Dist[i], i == N - 1 ? "\n":" ");
for( int i = V2; i != -1; i = Path[i] )
printf("%d ", i);
printf("\n%d", nPath[V2]);
}
}
邻接矩阵
#include <cstdio>
#include <algorithm>
using namespace std;
#define INF 0x7FFFFFFF
int G[500][500], Dist[500], Path[500], nPath[500];
bool check( int N )
{
bool flag = false;
for( int i = 0; i < N; ++i )
for( int j = 0; j < N; ++j )
if( G[i][j] != INF && Dist[i] != INF && Dist[j] >= Dist[i] + G[i][j] )
{
if( Dist[j] > Dist[i] + G[i][j] )
{
flag = true;
Dist[j] = Dist[i] + G[i][j];
Path[j] = i;
nPath[j] = nPath[i];
}
else if( i != Path[j] )
nPath[j] += nPath[i];
}
return flag;
}
bool BF( int N )
{
for( int i = 0; i < N - 1; ++i )
if( !check(N) )
return true;
return !check(N);
}
int main()
{
int N, M, V1, V2, a, b, w;
scanf("%d %d %d %d", &N, &M, &V1, &V2);
fill( G[0], G[0] + 500 * 500, INF );
fill( Dist, Dist + N, INF );
fill( Path, Path + N, -1 );
nPath[V1] = 1;
Dist[V1] = 0;
for( int i = 0; i < M; ++i )
{
scanf("%d %d %d", &a, &b, &w);
G[a][b] = w;
}
if( BF( N ) )
{
for( int i = 0; i < N; ++i )
printf("%d%s", Dist[i], i == N - 1 ? "\n":" ");
for( int i = V2; i != -1; i = Path[i] )
printf("%d ", i);
printf("\n%d", nPath[V2]);
}
else printf("FALSE");
}
测试用例:给点节点数与路径数, 给定任意两存在节点,输出最短距离,及最短路径
6 8 0 2
0 1 1
0 3 4
0 4 4
1 3 2
2 5 1
3 2 2
3 4 3
4 5 3