1.floyd
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 405 ;
int n, m;
int f[ MAXN] [ MAXN] ;
int sum[ MAXN] [ MAXN] ;
int main ( )
{
scanf ( "%d" , & n) ;
for ( int i = 1 ; i <= n; i++ ) {
for ( int j = 1 ; j <= n; j++ ) {
scanf ( "%d" , & f[ i] [ j] ) ;
if ( f[ i] [ j] ) sum[ i] [ j] = 1 ;
if ( ! f[ i] [ j] && i != j) f[ i] [ j] = 1e9 + 7 ;
}
}
for ( int k = 1 ; k <= n; k++ )
for ( int i = 1 ; i <= n; i++ )
for ( int j = 1 ; j <= n; j++ )
if ( f[ i] [ j] > f[ i] [ k] + f[ k] [ j] )
f[ i] [ j] = f[ i] [ k] + f[ k] [ j] , sum[ i] [ j] = sum[ i] [ k] * sum[ k] [ j] ;
else if ( f[ i] [ j] == f[ i] [ k] + f[ k] [ j] ) sum[ i] [ j] + = sum[ i] [ k] * sum[ k] [ j] ;
for ( int i = 1 ; i <= n; i++ ) {
for ( int j = 1 ; j <= n; j++ ) printf ( "%d " , f[ i] [ j] ) ;
printf ( "\n" ) ;
}
for ( int i = 1 ; i <= n; i++ ) {
for ( int j = 1 ; j <= n; j++ ) printf ( "%d " , sum[ i] [ j] ) ;
printf ( "\n" ) ;
}
return 0 ;
}
2.dijkstra
#include <iostream>
#include <iomanip>
#include <string>
#define INF 0x3f3f3f3f
using namespace std;
#define vertexNum 5
int G[ vertexNum] [ vertexNum] ;
string vertex[ ] = { "A" , "B" , "C" , "D" , "E" } ;
void CreateMGraph ( )
{
for ( int i= 0 ; i< vertexNum; i++ )
for ( int j= 0 ; j< vertexNum; j++ )
{
G[ i] [ j] = INF;
}
G[ 0 ] [ 1 ] = 10 ; G[ 0 ] [ 3 ] = 30 ; G[ 0 ] [ 4 ] = 100 ;
G[ 1 ] [ 2 ] = 50 ;
G[ 2 ] [ 4 ] = 10 ;
G[ 3 ] [ 2 ] = 20 ; G[ 3 ] [ 4 ] = 60 ;
}
void Dijkstra ( int v)
{
int w[ vertexNum] ;
int i, num, k, min;
string path[ vertexNum] ;
int s[ vertexNum] = { 0 } ;
cout<< "初始权值数组和路径字符串数组:" << endl;
for ( i= 0 ; i< vertexNum; i++ )
{
w[ i] = G[ v] [ i] ;
path[ i] = vertex[ v] + "-->" + vertex[ i] ;
cout<< path[ i] << " " ;
if ( w[ i] != INF) cout << w[ i] << endl;
else cout<< "∞" << endl;
}
s[ v] = 1 ;
w[ v] = 0 ;
num = 1 ;
cout << "打印源点A到各点的最短路径及其权值和:" << endl;
while ( num <= vertexNum)
{
min= INF;
for ( k= 0 , i= 0 ; i< vertexNum; i++ )
{
if ( s[ i] == 0 && ( w[ i] < min) )
{
min = w[ i] ;
k= i;
}
}
cout << path[ k] << " " << w[ k] << endl;
s[ k] = 1 ;
num++ ;
for ( i= 0 ; i< vertexNum; i++ )
{
if ( ( w[ i] > w[ k] + G[ k] [ i] ) && ( G[ k] [ i] != INF) )
{
w[ i] = w[ k] + G[ k] [ i] ;
path[ i] = path[ k] + "-->" + vertex[ i] ;
}
}
}
}
int main ( )
{
CreateMGraph ( ) ;
cout << "打印邻接矩阵:" << endl;
for ( int i= 0 ; i < vertexNum; i++ ) {
for ( int j= 0 ; j < vertexNum; j++ ) {
if ( G[ i] [ j] == INF) cout << setw ( 4 ) << "∞" ;
else cout << setw ( 4 ) << G[ i] [ j] ;
if ( j == vertexNum- 1 ) cout << endl;
}
}
Dijkstra ( 0 ) ;
return 0 ;
}
#include <iostream>
#include <cstring>
#include <climits>
#include <queue>
#include <cstdio>
#define fi first
#define se second
#define REP(I, A, B) for(int I = A; I <= B; I++)
using namespace std;
const int MAXN = 1e4 + 5 ;
const int MAXM = 5e5 + 5 ;
const int INF = INT_MAX;
int d[ MAXN] , head[ MAXN] ;
int nxt[ MAXM] , val[ MAXM] , to[ MAXM] , size;
int n, m, s;
typedef pair< int , int > pii;
priority_queue < pii, vector< pii> , greater< pii> > q;
inline void AddEdge ( int u, int v, int w) {
nxt[ ++ size] = head[ u] ;
to[ head[ u] = size] = v;
val[ size] = w;
}
inline int read ( ) {
int x = 0 ; char ch = getchar ( ) ;
while ( ! isdigit ( ch) ) ch = getchar ( ) ; while ( isdigit ( ch) ) x = x * 10 + ch - '0' , ch = getchar ( ) ;
return x;
}
int main ( ) {
n = read ( ) , m = read ( ) ; s = read ( ) ;
REP ( i, 1 , m) {
int a = read ( ) , b = read ( ) , c = read ( ) ;
AddEdge ( a, b, c) ;
}
REP ( i, 1 , n) d[ i] = INF;
q. push ( pii ( d[ s] = 0 , s) ) ;
REP ( i, 1 , n) {
while ( d[ q. top ( ) . se] != q. top ( ) . fi) q. pop ( ) ;
pii now = q. top ( ) ;
q. pop ( ) ;
for ( int e = head[ now. se] ; e; e = nxt[ e] ) {
if ( d[ to[ e] ] > val[ e] + now. fi) {
d[ to[ e] ] = val[ e] + now. fi;
q. push ( pii ( d[ to[ e] ] , to[ e] ) ) ;
}
}
}
REP ( i, 1 , n) printf ( "%d%c" , d[ i] , " \n" [ i == n] ) ;
return 0 ;
}
#include <iostream>
#include <cstdio>
#define MAX 1000000
using namespace std;
int arcs[ 10 ] [ 10 ] ;
int D[ 10 ] ;
int p[ 10 ] [ 10 ] ;
int final[ 10 ] ;
int n = 0 ;
int v0 = 0 ;
int v, w;
void ShortestPath_DIJ ( )
{
for ( v = 0 ; v < n; v++ )
{
final[ v] = 0 ; D[ v] = arcs[ v0] [ v] ;
for ( w = 0 ; w < n; w++ ) p[ v] [ w] = 0 ;
if ( D[ v] < MAX) { p[ v] [ v0] = 1 ; p[ v] [ v] = 1 ; }
}
D[ v0] = 0 ; final[ v0] = 1 ;
for ( int i = 1 ; i < n; i++ )
{
int min = MAX;
for ( w = 0 ; w < n; w++ )
{
if ( ! final[ w] )
{
if ( D[ w] < min) { v = w; min = D[ w] ; }
}
}
final[ v] = 1 ;
for ( w = 0 ; w < n; w++ )
{
if ( ! final[ w] && ( min+ arcs[ v] [ w] < D[ w] ) )
{
D[ w] = min + arcs[ v] [ w] ;
p[ w] [ w] = 1 ;
}
}
}
}
int main ( )
{
cin >> n;
for ( int i = 0 ; i < n; i++ )
{
for ( int j = 0 ; j < n; j++ )
{
cin >> arcs[ i] [ j] ;
}
}
ShortestPath_DIJ ( ) ;
for ( int i = 0 ; i < n; i++ ) printf ( "D[%d] = %d\n" , i, D[ i] ) ;
return 0 ;
}
3.spaf
#include <iostream>
#include <vector>
#include <list>
using namespace std;
struct Edge
{
int to, len;
} ;
bool spfa ( const int & beg,
const vector< list< Edge> > & adjlist,
vector< int > & dist,
vector< int > & path)
{
const int INF= 0x7FFFFFFF , NODE= adjlist. size ( ) ;
dist. assign ( NODE, INF) ;
path. assign ( NODE, - 1 ) ;
list< int > que ( 1 , beg) ;
vector< int > cnt ( NODE, 0 ) ;
vector< bool > flag ( NODE, 0 ) ;
dist[ beg] = 0 ;
cnt[ beg] = flag[ beg] = 1 ;
while ( ! que. empty ( ) )
{
const int now= que. front ( ) ;
que. pop_front ( ) ;
flag[ now] = 0 ;
for ( list< Edge> :: const_iterator
i= adjlist[ now] . begin ( ) ; i!= adjlist[ now] . end ( ) ; ++ i)
if ( dist[ i- > to] > dist[ now] + i- > len)
{
dist[ i- > to] = dist[ now] + i- > len;
path[ i- > to] = now;
if ( ! flag[ i- > to] )
{
if ( NODE== ++ cnt[ i- > to] ) return 1 ;
if ( ! que. empty ( ) && dist[ i- > to] < dist[ que. front ( ) ] )
que. push_front ( i- > to) ;
else que. push_back ( i- > to) ;
flag[ i- > to] = 1 ;
}
}
}
return 0 ;
}
int main ( )
{
int n_num, e_num, beg;
cout<< "输入点数、边数、出发点:" ;
cin>> n_num>> e_num>> beg;
vector< list< Edge> > adjlist ( n_num, list< Edge> ( ) ) ;
for ( int i= 0 , p; i!= e_num; ++ i)
{
Edge tmp;
cout<< "输入第" << i+ 1 << "条边的起点、终点、长度:" ;
cin>> p>> tmp. to>> tmp. len;
adjlist[ p] . push_back ( tmp) ;
}
vector< int > dist, path;
if ( spfa ( beg, adjlist, dist, path) ) cout<< "图中存在负权回路\n" ;
else for ( int i= 0 ; i!= n_num; ++ i)
{
cout<< beg<< "到" << i<< "的最短距离为" << dist[ i] << ",反向打印路径:" ;
for ( int w= i; path[ w] >= 0 ; w= path[ w] ) cout<< w<< "<-" ;
cout<< beg<< '\n' ;
}
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define REP(I, A, B) for(int I = (A); I <= (B); I++)
const int INF = 0x7ffffff ;
const int MAXN = 1e5 + 5 ;
const int MAXM = 5e5 + 5 ;
int tot, n, m, s;
int d[ MAXN] , head[ MAXN] , nxt[ MAXM] , val[ MAXM] , to[ MAXM] , path[ MAXN] ;
bool vis[ MAXN] ;
queue< int > q;
inline void AddEdge ( int u, int v, int w) {
nxt[ ++ tot] = head[ u] ;
to[ head[ u] = tot] = v;
val[ tot] = w;
}
inline int read ( ) {
char ch = getchar ( ) ;
int ans = 0 ;
while ( ! isdigit ( ch) ) ch = getchar ( ) ;
while ( isdigit ( ch) ) ans = ans * 10 + ( ch - '0' ) , ch = getchar ( ) ;
return ans;
}
void print_path ( int v) {
if ( path[ v] ) print_path ( path[ v] ) ;
printf ( "%d " , v) ;
}
int main ( ) {
n = read ( ) , m = read ( ) ; s = 1 ;
REP ( i, 1 , m) {
int a = read ( ) , b = read ( ) , c = read ( ) ;
AddEdge ( a, b, c) , AddEdge ( b, a, c) ;
}
REP ( i, 1 , n) d[ i] = INF;
vis[ s] = 1 ; q. push ( s) ; d[ s] = 0 ;
while ( ! q. empty ( ) ) {
int t = q. front ( ) ; q. pop ( ) ; vis[ t] = 0 ;
for ( int e = head[ t] ; e; e = nxt[ e] ) {
if ( d[ to[ e] ] > d[ t] + val[ e] ) {
d[ to[ e] ] = d[ t] + val[ e] ; path[ to[ e] ] = t;
if ( ! vis[ to[ e] ] ) vis[ to[ e] ] = 1 , q. push ( to[ e] ) ;
}
}
}
REP ( i, 1 , n) printf ( "Node: %d | Len: %d | Path:" , i, d[ i] ) ;
return 0 ;
}
4.算法解析( TODO)