基础最短路总结

最短路

Problem Description
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?

 
Input
输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
输入保证至少存在1条商店到赛场的路线。
 
Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
 
Sample Input
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0
Sample Output
3
2
 
题目来源:hdu2544
 
总结:就让这题来总结一下最短路吧……
图中顶点数用 v 表示,边数用 e 表示;
最短路几个常用算法:dijkstra 、floyd 、spfa 、bellman_ford
 
一、时间复杂度
dijkstra      邻接矩阵:O(v^2)
floyd         邻接矩阵:O(v^3)
spfa          邻接表:  O(k*e)(k为常数)
bellman_ford  邻接矩阵:O(v^3) 邻接表:O(v*e)
 
二、注意点
1、dijkstra      (单源最短路)
a、只能求最短路,不能求最长路;1 2 2;1 3 1;2 4 1;3 4 3;1->4的最短路
b、权值只能为正;1 2 3 ;1 3 2 ;2 3 -2 ;以1为源点
 
2、floyd         (每对顶点最短路)
a、喜欢把变量顺序写成 i->j->k (k->i->j)
b、可以处理负数
 
3、spfa          (单源最短路)
a、可以求最长路;
b、可以求最值路的路径;
 
4、bellman_ford  (单源最短路)
a、不能求有负环的所有路径
 
dijkstra(邻接矩阵)
View Code
 1 #include<iostream>
 2 #define INF 10000000
 3 #define N 110
 4 
 5 using namespace std;
 6 
 7 int map[N][N],visited[N],d[N],lowcost[N];
 8 
 9 void dijkstra(int s,int n)
10 {
11     int i,j,k,min;
12     for(i=1;i<=n;i++)
13     {
14         visited[i]=false;
15         d[i]=INF;
16     }
17     for(i=1;i<=n;i++)
18     {
19         lowcost[i]=map[s][i];
20     }
21     d[s]=0;
22     visited[s]=true;
23     for(i=1;i<n;i++) //这里要注意 不要写成i<=n
24     {
25         min=INF;
26         for(j=1;j<=n;j++)
27         {
28             if(!visited[j]&&min>lowcost[j])
29             {
30                 min=lowcost[j];
31                 k=j;
32             }
33         }
34         d[k]=min;
35         visited[k]=true;
36         for(j=1;j<=n;j++)
37         {
38             if(!visited[j]&&lowcost[j]>d[k]+map[k][j])
39             {
40                 lowcost[j]=d[k]+map[k][j];
41             }
42         }
43     }
44 }
45 
46 int main()
47 {
48     int n,m,u,v,w,i;
49     while(cin>>n>>m&&(n|m))
50     {
51         for(u=1;u<=n;u++)
52         {
53             for(v=1;v<=n;v++)
54             {
55                 map[u][v]=(u==v?0:INF);
56             }
57         }
58         for(i=1;i<=m;i++)
59         {
60             cin>>u>>v>>w;
61             map[v][u]=map[u][v]=w;
62         }
63         dijkstra(1,n);
64         cout<<d[n]<<endl;
65     }
66     return 0;
67 }

 

floyd(邻接矩阵)

View Code
 1 #include<iostream>
 2 #define INF 10000000
 3 #define N 110
 4 
 5 using namespace std;
 6 
 7 int d[N][N];
 8 
 9 void floyd(int n)
10 {
11     int k,i,j;
12     for(k=1;k<=n;k++)
13     {
14         for(i=1;i<=n;i++)
15         {
16             for(j=1;j<=n;j++)
17             {
18                 if(d[i][j]>d[i][k]+d[k][j])
19                 {
20                     d[i][j]=d[i][k]+d[k][j];
21                 }
22             }
23         }
24     }
25 }
26 
27 int main()
28 {
29     int n,m,u,v,w,i;
30     while(cin>>n>>m&&(n|m))
31     {
32         for(u=1;u<=n;u++)
33         {
34             for(v=1;v<=n;v++)
35             {
36                 d[u][v]=(u==v?0:INF);
37             }
38         }
39         for(i=1;i<=m;i++)
40         {
41             cin>>u>>v>>w;
42             d[u][v]=d[v][u]=w;
43         }
44         floyd(n);
45         cout<<d[1][n]<<endl;
46     }
47     return 0;
48 }

 

spfa (vector建邻接表)

View Code
 1 #include<iostream>
 2 #include<string.h>
 3 #include<vector>
 4 #include<queue>
 5 #define INF 1000000000
 6 #define N 110
 7 using namespace std;
 8 
 9 struct edge{int v,w;};
10 int n,d[N];
11 bool visited[N];
12 vector<edge>e[N];
13 
14 void SPFA(int s)
15 {
16     int temp,tv;
17     queue<int>Q;
18     while(!Q.empty()) Q.pop();
19     Q.push(s);
20     d[s]=0;
21     visited[s]=true;
22     while(!Q.empty())
23     {
24         temp=Q.front();
25         vector<edge>::iterator it;
26         for(it=e[temp].begin();it<e[temp].end();it++)
27         {
28             tv=it->v;
29             if(d[tv]>d[temp]+it->w)
30             {
31                 d[tv]=d[temp]+it->w;
32                 if(!visited[tv])
33                 {
34                     Q.push(tv);
35                     visited[tv]=true;
36                 }
37             }
38         }
39         Q.pop();
40         visited[temp]=false;
41     }
42 }
43 
44 int main()
45 {
46     int m,u,v,w,i;
47     while(cin>>n>>m&&(n|m))
48     {
49         edge t;
50         for(i=1;i<=n;i++)
51         {
52             e[i].clear();
53             d[i]=INF;
54             visited[i]=false;
55         }
56         for(i=1;i<=m;i++)
57         {
58             cin>>u>>v>>w;
59             t.v=v;t.w=w;
60             e[u].push_back(t);
61             t.v=u;
62             e[v].push_back(t);
63         }
64         SPFA(1);
65         cout<<d[n]<<endl;
66     }
67     return 0;
68 }

 

bellman_ford(邻接矩阵)

View Code
 1 #include<iostream>
 2 #define INF 10000000
 3 #define N 110
 4 
 5 using namespace std;
 6 
 7 int map[N][N],d[N];
 8 
 9 bool bellman_ford(int s,int n)
10 {
11     int i,u,v;
12     for(i=1;i<=n;i++) d[i]=INF;
13     d[s]=0;
14     for(i=1;i<n;i++)
15     {
16         for(u=1;u<=n;u++)
17         {
18             for(v=1;v<=n;v++)
19             {
20                 if(map[u][v]<INF&&d[v]>d[u]+map[u][v])
21                 {
22                     d[v]=d[u]+map[u][v];
23                 }
24             }
25         }
26     }
27     for(u=1;u<=n;u++)
28     {
29         for(v=1;v<=n;v++)
30         {
31             if(map[u][v]<INF&&d[v]>d[u]+map[u][v])
32             {
33                 return false;
34             }
35         }
36     }
37     return true;
38 }
39 
40 int main()
41 {
42     int n,m,u,v,w,i;
43     while(cin>>n>>m&&n|m)
44     {
45         for(u=1;u<=n;u++)
46         {
47             for(v=1;v<=n;v++)
48             {
49                 map[u][v]=(u==v?0:INF);
50             }
51         }
52         for(i=1;i<=m;i++)
53         {
54             cin>>u>>v>>w;
55             map[v][u]=map[u][v]=w;
56         }
57         if(bellman_ford(1,n))
58         {
59             cout<<d[n]<<endl;
60         }
61     }
62 }

 

 

posted @ 2012-07-15 00:00  mtry  阅读(427)  评论(0)    收藏  举报