Dijkstra算法
详细介绍
Dijkstra复杂度是O(N^2),如果用binary heap优化可以达到O((E+N)logN),用fibonacci heap可以优化到O(NlogN+E)
其基本思想是采用贪心法,对于每个节点v[i],维护估计最短路长度最大值,每次取出一个使得该估计值最小的t,并采用与t相连的边对其余点的估计值进行更新,更新后不再考虑t。
在此过程中,估计值单调递减,所以可以得到确切的最短路。
Floyd-Warshall算法
详细介绍
Floyd是计算每对点间最短路径(APSP)的经典算法。
时间复杂度是雷打不动的O(n^3)
*Floyd-Warshall算法的基本思想:
它的基本思想就是动态规划。假设在一个图中有一条从结点A经过B、C、D到达E的路径是最短的,那么从A到B、C、D的路径也分别是最短的。用反证法证明,假如A到D的路径不是最短的,那么加上D到E的路径长度必然比原来的所谓最短长度小,与假设矛盾。
假设k点是结点i到j的路径的一个中间结点,如果路径ik和路径kj都是最短路径,那么ik+kj组成的路径ij必然是最短路径。
通过上面的观察,我们可以推出判断两点(设为i、j)之间的最短路径其实是求出 ij直接相连的距离、i通过其他结点k到达j的距离(即ik + kj)的最小值。
Bellman-Ford算法
详细介绍
Bellman-Ford主要是用于负权图。Bellman-Ford算法即标号修正算法。
实践中常用到的方法通常是FIFO标号修正算法和一般标号修正算法的Dequeue实现。
前者最坏时间复杂度是O(nm), 是解决任意边权的单源最短路经问题的最优强多项式算法。
也可以用这个算法判断是否存在负权回路.
迭代算法的思想:不停地调整图中的顶点值(源点到该点的最短路径值),直到没有点的值调整了为止。
- SPFA算法
Input:
6 1
0 50 10 0 45 0
0 0 15 0 10 0
20 0 0 15 0 0
0 20 0 0 35 0
0 0 0 30 0 0
0 0 0 3 0 0
1 4
Output:
25
1->3->4
Dijkstra:
2 * Problem: 最短路
3 * Author: Xu Fei
4 * Time: 2010.8.1 15:30
5 * Memo: Dijkstra
6 */
7
8 #include < iostream >
9 #include < cstdio >
10 using namespace std;
11
12 const int INF = 0xFFFFFFF ;
13
14 int N,M;
15 int S[ 100 ];
16 int T[ 100 ];
17 int pre[ 100 ];
18 int dis[ 100 ];
19 int cost[ 100 ][ 100 ];
20 bool vis[ 100 ];
21
22 void init()
23 {
24 int i,j;
25
26 scanf( " %d%d " , & N, & M);
27 for (i = 1 ;i <= N; ++ i)
28 for (j = 1 ;j <= N; ++ j)
29 {
30 scanf( " %d " , & cost[i][j]);
31 if (cost[i][j] == 0 )
32 cost[i][j] = INF;
33 }
34 for (i = 1 ;i <= M; ++ i)
35 scanf( " %d%d " , & S[i], & T[i]);
36 }
37 int dijkstra( int s, int t)
38 {
39 int i,j,Min,kj;
40
41 for (i = 1 ;i <= N; ++ i)
42 {
43 dis[i] = cost[s][i];
44 vis[i] = true ;
45 pre[i] = s;
46 }
47 dis[s] = 0 ; vis[s] = false ;
48 for (i = 1 ;i < N; ++ i)
49 {
50 Min = INF;
51 for (j = 1 ;j <= N; ++ j)
52 if (vis[j] && dis[j] < Min)
53 Min = dis[j],kj = j;
54 if (kj == t) break ;
55 vis[kj] = false ;
56 for (j = 1 ;j <= N; ++ j)
57 if (vis[j] && dis[j] > dis[kj] + cost[kj][j])
58 {
59 dis[j] = dis[kj] + cost[kj][j];
60 pre[j] = kj;
61 }
62 }
63 return dis[t];
64 }
65 void dfs( int s, int t)
66 {
67 if (s == t)
68 printf( " %d " ,s);
69 else
70 {
71 dfs(s,pre[t]);
72 printf( " ->%d " ,t);
73 }
74 }
75 void solve()
76 {
77 int i;
78
79 for (i = 1 ;i <= M; ++ i)
80 {
81 printf( " %d\n " ,dijkstra(S[i],T[i]));
82 dfs(S[i],T[i]);
83 printf( " \n " );
84 }
85 }
86 int main()
87 {
88 freopen( " zui.in " , " r " ,stdin);
89 freopen( " zui.out " , " w " ,stdout);
90
91 init();
92 solve();
93 return 0 ;
94 }
95
Floyd:
2 * Problem: 最短路
3 * Author: Xu Fei
4 * Time: 2010.8.1 16.12
5 * Method: Floyd
6 */
7
8 #include < iostream >
9 #include < cstdio >
10 using namespace std;
11
12 const int INF = 0xFFFFFFF ;
13
14 int N,M;
15 int S[ 100 ];
16 int T[ 100 ];
17 int mid[ 100 ][ 100 ];
18 int cost[ 100 ][ 100 ];
19
20 void init()
21 {
22 int i,j;
23
24 scanf( " %d%d " , & N, & M);
25 for (i = 1 ;i <= N; ++ i)
26 for (j = 1 ;j <= N; ++ j)
27 {
28 scanf( " %d " , & cost[i][j]);
29 if (i != j && cost[i][j] == 0 )
30 cost[i][j] = INF;
31 mid[i][j] = 0 ;
32 }
33 for (i = 1 ;i <= M; ++ i)
34 scanf( " %d%d " ,S + i,T + i);
35 }
36 void floyd()
37 {
38 int i,j,k;
39
40 for (k = 1 ;k <= N; ++ k)
41 for (i = 1 ;i <= N; ++ i)
42 if (i != k)
43 for (j = 1 ;j <= N; ++ j)
44 if (j != k && j != i)
45 if (cost[i][j] > cost[i][k] + cost[k][j])
46 {
47 cost[i][j] = cost[i][k] + cost[k][j];
48 mid[i][j] = k;
49 }
50 }
51 void dfs( int s, int t)
52 {
53 if (mid[s][t] == 0 ) return ;
54 dfs(s,mid[s][t]);
55 printf( " ->%d " ,mid[s][t]);
56 dfs(mid[s][t],t);
57 }
58 void solve()
59 {
60 int i;
61
62 floyd();
63 for (i = 1 ;i <= M; ++ i)
64 {
65 printf( " %d\n " ,cost[S[i]][T[i]]);
66 printf( " %d " ,S[i]);
67 dfs(S[i],T[i]);
68 printf( " ->%d\n " ,T[i]);
69 }
70 }
71 int main()
72 {
73 freopen( " zui.in " , " r " ,stdin);
74 freopen( " zui.out " , " w " ,stdout);
75
76 in it ();
77 solve();
78 return 0 ;
79 }
Ford:
2 * Problem: 最短路
3 * Author: Xu Fei
4 * Time: 2010.8.1 16.46
5 * Method: Ford
6 */
7
8 #include < iostream >
9 #include < cstdio >
10 using namespace std;
11
12 const int INF = 0xFFFFFFF ;
13
14 int N,M;
15 bool flag;
16 int S[ 100 ];
17 int T[ 100 ];
18 int dis[ 100 ];
19 int pre[ 100 ];
20 int cost[ 100 ][ 100 ];
21
22 void in it ()
23 {
24 int i,j;
25
26 scanf( " %d%d " , & N, & M);
27 for (i = 1 ;i <= N; ++ i)
28 for (j = 1 ;j <= N; ++ j)
29 {
30 scanf( " %d " , & cost[i][j]);
31 if (i != j && cost[i][j] == 0 )
32 cost[i][j] = INF;
33 }
34 for (i = 1 ;i <= M; ++ i)
35 scanf( " %d%d " ,S + i,T + i);
36 }
37 int ford( int s, int t)
38 {
39 int i,j;
40
41 for (i = 1 ;i <= N; ++ i)
42 {
43 dis[i] = INF;
44 pre[i] = i;
45 }
46 dis[s] = 0 ;
47 do {
48 flag = false ;
49 for (i = 1 ;i <= N; ++ i)
50 if (dis[i] < INF)
51 for (j = 1 ;j <= N; ++ j)
52 if (dis[j] > dis[i] + cost[i][j])
53 {
54 dis[j] = dis[i] + cost[i][j];
55 pre[j] = i;
56 flag = true ;
57 }
58 } while (flag);
59 return dis[t];
60 }
61 void dfs( int s, int t)
62 {
63 if (s == t) return ;
64 dfs(s,pre[t]);
65 printf( " %d-> " ,pre[t]);
66 }
67 void solve()
68 {
69 int i;
70
71 for (i = 1 ;i <= M; ++ i)
72 {
73 printf( " %d\n " ,ford(S[i],T[i]));
74 dfs(S[i],T[i]);
75 printf( " %d\n " ,T[i]);
76 }
77 }
78 int main()
79 {
80 freopen( " zui.in " , " r " ,stdin);
81 freopen( " zui.out " , " w " ,stdout);
82
83 in it ();
84 solve();
85 return 0 ;
86 }