HDU 2544 最短路(floyd+bellman-ford+spfa+dijkstra队列优化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544

题目大意:找点1到点n的最短路(无向图)

练一下最短路。。。

dijkstra+队列优化:

 1 #include<iostream>
 2 #include<functional>  
 3 #include<vector>
 4 #include<queue>
 5 using namespace std;
 6 typedef pair<int, int> p;//first是最短距离,second是顶点编号 
 7 const int N = 105;
 8 const int INF = 1 << 29;
 9 
10 struct edge {
11     int to, cost;//邻接的点,以及到该点的权值 
12 };
13 
14 vector<edge>eg[N];//邻接表
15 bool used[N];//表示是否已被使用过 
16 int d[N];//最短距离 
17 int V, E;//顶点数和边数 
18 
19 void dijistra(int s) {
20     //优先队列,按first从小到大顺序
21     priority_queue<p, vector<p>, greater<p> >q;
22     //初始化 
23     for (int i = 1; i <= V; i++) {
24         d[i] = INF;
25         used[i] = false;
26     }
27     d[s] = 0;
28 
29     q.push(p(0, s));
30     while (!q.empty()) {
31         p p1 = q.top();
32         q.pop();
33         int v = p1.second;
34         if (used[v])    continue;
35         used[v] = true;
36         for (int i = 0; i<eg[v].size(); i++) {
37             edge e = eg[v][i];
38             if (d[e.to]>d[v] + e.cost) {
39                 d[e.to] = d[v] + e.cost;
40                 q.push(p(d[e.to], e.to));
41             }
42         }
43     }
44 }
45 
46 int main() {
47     while (cin >> V >> E && (V || E)) {
48         for(int i=1;i<=V;i++){
49             eg[i].clear();
50         } 
51         for (int i = 1; i <= E; i++) {
52             int a, b, cost;
53             cin >> a >> b >> cost;
54             edge g1, g2;
55             g1.to = b, g2.to = a;
56             g1.cost = g2.cost = cost;
57             eg[a].push_back(g1);
58             eg[b].push_back(g2);
59         }
60         dijistra(1);
61         cout << d[V] << endl;
62     }
63 }

bellman-ford:

 1 /*
 2 bellman-ford
 3 */
 4 #include<iostream>
 5 #include<cstring>
 6 using namespace std;
 7 const int N=100005;
 8 const int INF=1<<30;
 9 
10 struct edge{
11     int from,to,cost;
12 }es[N];//
13 
14 int d[N];//出发点到i的最短距离 
15 int V,E;//顶点数、边数
16 
17 //求解从顶点s出发到所有点的最短距离 
18 void shortest_path(int s){
19     for(int i=1;i<=V;i++) d[i]=INF;
20     d[s]=0;
21     while(true){
22         bool update=false;
23         for(int i=1;i<=E;i++){
24             edge e=es[i];
25             if(d[e.from]!=INF&&d[e.to]>d[e.from]+e.cost){
26                 d[e.to]=d[e.from]+e.cost;
27                 update=true;
28             }
29             //双向 
30             if(d[e.to]!=INF&&d[e.from]>d[e.to]+e.cost){
31                 d[e.from]=d[e.to]+e.cost;
32                 update=true;
33             }
34             
35         }
36         if(!update) break;
37     }
38 }
39 
40 int main(){
41     int n,m;
42     while(cin>>V>>E&&(V||E)){
43         for(int i=1;i<=E;i++){
44             cin>>es[i].from>>es[i].to>>es[i].cost;
45         }
46         shortest_path(1);
47         cout<<d[V]<<endl;
48     } 
49 }

floyd:

 1 /*floyd*/
 2 #include<iostream>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=105;
 6 const int INF=1<<29;
 7 int map[N][N];//map[i][j]表示边i~j的距离
 8 
 9 int V,E;//顶点数,边数
10  
11 void floyd(){
12     for(int k=1;k<=V;k++)
13         for(int i=1;i<=V;i++)
14             for(int j=1;j<=V;j++)
15                 map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
16 }
17 
18 int main(){
19     while(cin>>V>>E&&(V||E)){
20         for(int i=1;i<=V;i++){
21             for(int j=1;j<=V;j++){
22                 if(i==j) 
23                     map[i][j]=0;
24                 else 
25                     map[i][j]=INF;
26             }
27         }
28         for(int i=1;i<=E;i++){
29             int a,b,cost;
30             cin>>a>>b>>cost;
31             map[a][b]=map[b][a]=cost;
32         }
33         floyd();
34         cout<<map[1][V]<<endl;
35     }
36 }

spfa:

 1 /*spfa*/
 2 #include<iostream>
 3 #include<queue>
 4 #include<algorithm>
 5 using namespace std;
 6 const int N=105;
 7 const int INF=1<<29;
 8 
 9 int map[N][N];
10 int d[N];//距离起点最小距离 
11 bool used[N];//点是否在队列中 
12 int V,E;//顶点数,边数
13 
14 //求解从顶点s出发到所有点的最短距离 
15 void spfa(int s){
16     //初始化
17     for(int i=1;i<=V;i++){
18         d[i]=INF;
19         used[i]=false;
20     }
21     d[s]=0;
22     
23     queue<int>q;
24     q.push(s);
25     used[s]=true;
26     while(!q.empty()){
27         int k=q.front();
28         q.pop();
29         used[k]=false; 
30         //此处实际上可以不用遍历所有点,能够用邻接表优化 
31         for(int i=1;i<=V;i++){
32             if(d[i]>d[k]+map[k][i]){
33                 d[i]=d[k]+map[k][i];
34                 //这个点更新后要入队,要判断是否已经在队列中 
35                 if(!used[i]){
36                     q.push(i);
37                     used[i]=true; 
38                 } 
39             } 
40         }
41     } 
42 }
43 
44 int main(){
45     while(cin>>V>>E&&(V||E)){
46         //初始化 
47         for(int i=1;i<=V;i++)
48             for(int j=1;j<=V;j++)
49                 map[i][j]=(i==j?0:INF);
50         
51         for(int i=1;i<=E;i++){
52             int a,b,cost;
53             cin>>a>>b>>cost;
54             map[a][b]=map[b][a]=cost;
55         }
56         spfa(1);
57         cout<<d[V]<<endl;
58     } 
59 }
60  
原文地址:https://www.cnblogs.com/fu3638/p/6980372.html