xfstart07
Get busy living or get busy dying
最短路径算法复习:

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经过BCD到达E的路径是最短的,那么从ABCD的路径也分别是最短的。用反证法证明,假如AD的路径不是最短的,那么加上DE的路径长度必然比原来的所谓最短长度小,与假设矛盾。

     假设k点是结点ij的路径的一个中间结点,如果路径ik和路径kj都是最短路径,那么ik+kj组成的路径ij必然是最短路径。

     通过上面的观察,我们可以推出判断两点(设为ij)之间的最短路径其实是求出 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:

 1 /*
 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:

 1 /*
 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]==0return;
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     init();
77     solve();
78     return 0;
79 }


Ford:

 1 /*
 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 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(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     init();
84     solve();
85     return 0;
86 }

posted on 2010-08-01 15:44 xfstart07 阅读(156) 评论(0)  编辑 收藏 引用 所属分类: 算法学习图论

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理