基础最短路总结
最短路
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条商店到赛场的路线。
输入保证至少存在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
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
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
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
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 }
 
                    
                
 

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号