单源最短路问题

1.bellman-ford

 1 #include<iostream>
 2 #define INF 1000000
 3 using namespace std;
 4 struct edge
 5 {
 6     int from,to,cost;
 7     edge(){}
 8     edge(int ff,int tt,int cc)
 9     {
10         from=ff;
11         to=tt;
12         cost=cc;
13     }
14 };
15 const int maxn=105;
16 const int maxe=10005;
17 int d[maxn];
18 edge es[maxe];
19 int v,e;
20 
21 void bellman_ford(int s)
22 {
23     fill(d,d+v,INF);
24     d[s]=0;
25     while(true)
26     {
27         bool update=false;
28         for(int i=0;i<e;i++)
29         {
30             edge e=es[i];
31             if(d[e.from]!=INF&&d[e.to]>d[e.from]+e.cost)
32             {
33                 d[e.to]=d[e.from]+e.cost;
34                 update=true;
35             }
36         }
37         if(!update) break;
38     }
39     for(int i=0;i<v;i++)
40     {
41         cout<<d[i]<<endl;
42     }
43 }
44 //如果返回true则存在复圈
45 bool find_negative_loop()
46 {
47     fill(d,d+v,INF);
48     for(int i=0;i<v;i++)
49     {
50         for(int j=0;j<e;j++)
51         {
52             edge e=es[j];
53             if(d[e.to]>d[e.from]+e.cost)
54             {
55                 d[e.to]=d[e.from]+e.cost;
56 
57                 //如果第n次仍然更新了,则存在负圈
58                 if(i==v-1) return true;
59             }
60         }
61     }
62     return false;
63 }
64 int main()
65 {
66     cin>>v>>e;
67     int from,to,cost;
68     for(int i=0;i<e;i++)
69     {
70         cin>>from>>to>>cost;
71         from--;
72         to--;
73         es[i]=edge(from,to,cost);
74     }
75     //cout<<find_negative_loop();
76     bellman_ford(0);
77     return 0;
78 }
View Code

2.dijkstra

 1 #include<bits/stdc++.h>
 2 #define INF 1000000
 3 using namespace std;
 4 const int maxn=1010;
 5 //邻接矩阵形式
 6 int cost[maxn][maxn];
 7 int used[maxn];
 8 int d[maxn];
 9 int n;
10 int prev[maxn];//最短路上所有前驱结点
11 vector<int> get_path(int t)
12 {
13     vector<int> path;
14     for(;t!=-1;t=prev[t])
15         path.push_back(t);//不断沿着prev[t]走直到t=s
16     reverse(path.begin(),path.end());
17     return path;
18 }
19 void dijkstra(int s)
20 {
21     fill(d,d+n,INF);
22     fill(used,used+n,0);
23     fill(prev,prev+n,-1);
24     d[s]=0;
25     while(true)
26     {
27         int v=-1;
28         for(int u=0; u<n; u++)
29         {
30             if(!used[u]&&(v==-1||d[u]<d[v]))
31             {
32                 v=u;
33             }
34         }
35         if(v==-1) break;//所有节点都计算完毕
36         used[v]=1;
37         for(int u=0; u<n; u++)
38         {
39             if(d[u]>d[v]+cost[v][u])
40             {
41                 d[u]=d[v]+cost[v][u];
42                 prev[u]=v;
43             }
44         }
45     }
46     for(int i=0; i<n; i++)
47     {
48         cout<<d[i]<<endl;
49     }
50 
51     vector<int> path=get_path(n-1);
52     for(int i=0;i<path.size();i++)
53     {
54         cout<<path[i]<<" ";
55     }
56 }
57 
58 int main()
59 {
60     cin>>n;
61     for(int i=0; i<n; i++)
62     {
63         for(int j=0; j<n; j++)
64         {
65             cin>>cost[i][j];
66         }
67     }
68     dijkstra(0);
69     return 0;
70 }
71 /*
72 测试数据 教科书 P189 G6 的邻接矩阵 其中 数字 1000000 代表无穷大
73 6
74 1000000 1000000 10      100000      30      100
75 1000000 1000000 5       1000000     1000000 1000000
76 1000000 1000000 1000000 50          1000000 1000000
77 1000000 1000000 1000000 1000000     1000000 10
78 1000000 1000000 1000000 20          1000000 60
79 1000000 1000000 1000000 1000000     1000000 1000000
80 结果:
81 D[0]   D[1]   D[2]   D[3]   D[4]   D[5]
82  0   1000000   10     50     30     60
83 */
View Code

3.堆优化的dijkstra

 1 #include<iostream>
 2 #include<vector>
 3 #include<queue>
 4 #define INF 1000000
 5 using namespace std;
 6 typedef pair<int,int> P; //first代表最短距离,second代表顶点的编号
 7 //邻接表
 8 struct edge
 9 {
10     int to,cost;
11     edge(int tt,int cc)
12     {
13         to=tt;
14         cost=cc;
15     }
16 };
17 const int maxn=105;
18 vector<edge> G[maxn];
19 int d[maxn];
20 int n;
21 void heap_dijkstra(int s)
22 {
23     fill(d,d+n,INF);
24     priority_queue<P,vector<P>,greater<P> > que;
25     que.push(P(0,s));
26     d[s]=0;
27     while(!que.empty())
28     {
29         P p=que.top();
30         que.pop();
31         int v=p.second;
32         if(p.first>d[v]) continue;
33         for(int i=0;i<G[v].size();i++)
34         {
35             edge e=G[v][i];
36             if(d[e.to]>d[v]+e.cost)
37             {
38                 d[e.to]=d[v]+e.cost;
39                 que.push(P(d[e.to],e.to));
40             }
41         }
42     }
43     for(int i=0;i<n;i++)
44         cout<<d[i]<<endl;
45 }
46 int main()
47 {
48     cin>>n;
49     int from,to,cost;
50     for(int i=0;i<n;i++)
51     {
52         cin>>from>>to>>cost;
53         from--;
54         to--;
55         G[from].push_back(edge(to,cost));
56         G[to].push_back(edge(from,cost));
57     }
58 
59     heap_dijkstra(0);
60     return 0;
61 }
View Code

4.floyd_warshall

 1 #include<iostream>
 2 #include<memory.h>
 3 #define INF 1000000
 4 using namespace std;
 5 const int maxn=105;
 6 int d[maxn][maxn];
 7 int n;
 8 //任意两点间的最短路问题,dp
 9 void floyd_warshall()
10 {
11     for(int i=0; i<n; i++)
12         d[i][i]=0;
13 
14     for(int k=0; k<n; k++)
15         for(int i=0; i<n; i++)
16             for(int j=0; j<n; j++)
17                 d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
18 
19     for(int i=0; i<n; i++)
20         cout<<d[0][i]<<endl;
21 }
22 int main()
23 {
24     memset(d,INF,sizeof(d));
25     cin>>n;
26     for(int i=0; i<n; i++)
27         for(int j=0; j<n; j++)
28             cin>>d[i][j];
29 
30     floyd_warshall();
31     return 0;
32 }
View Code

5.spfa

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<vector>
 4 #include<queue>
 5 using namespace std;
 6 #define inf 99999999
 7 typedef struct dd
 8 {
 9     int a,d;
10 }node;
11 int dis[20005],n;
12 vector<node> maps[20005];
13 void sets()
14 {
15     for(int i=1;i<=n;i++)
16     {
17         dis[i]=inf;
18     }
19 }
20 void spfa()
21 {
22     queue<int> q;
23     int b[20005]={0},t;//b数组标识节点是否在队列中
24     q.push(1);//起点入队
25     b[1]=1;   //标记
26     dis[1]=0; //距离
27     while(!q.empty())
28     {
29         //队首元素出队
30         t=q.front();
31         q.pop();
32         //标记
33         b[t]=0;
34         //这个点作为起点的路径有多少
35         int len=maps[t].size();
36         int a;
37         for(int i=0;i<len;i++)
38         {
39             //这条路径的终点
40             a=maps[t][i].a;
41             if(dis[a]>maps[t][i].d+dis[t])
42             {
43                 dis[a]=maps[t][i].d+dis[t];
44                 if(!b[a])
45                 {
46                     b[a]=1;
47                     q.push(a);
48                 }
49             }
50         }
51     }
52 }
53 int main()
54 {
55     int m,a,b,l;
56     node Now;
57     while(scanf("%d%d",&n,&m)==2)
58     {
59         sets();
60         while(m--)
61         {
62             scanf("%d%d%d",&a,&b,&l);
63             Now.a=b;
64             Now.d=l;
65             maps[a].push_back(Now);
66         }
67         spfa();
68         for(int i=2;i<=n;i++)
69         {
70             printf("%d
",dis[i]);
71         }
72     }
73     return 0;
74 }
View Code
原文地址:https://www.cnblogs.com/wangkaipeng/p/6442491.html