最短路径问题 (最短路模板)

【题目描述】

    平面上有n个点(n≤100),每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点间的直线距离。现在的任务是找出从一点到另一点之间的最短路径。

【题目链接】

    http://ybt.ssoier.cn:8088/problem_show.php?pid=1342

【代码1】Floyd算法 O(n3

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int n,i,j,m,a,b,k,src,dst;
 4 pair<int,int> v[110];
 5 double d[110][110];
 6 int main()
 7 {
 8     memset(d,127,sizeof(d));
 9     scanf("%d",&n);
10     for(i=1;i<=n;i++) scanf("%d%d",&v[i].first,&v[i].second);
11     scanf("%d",&m);
12     for(i=1;i<=m;i++)
13         scanf("%d%d",&a,&b),d[a][b]=
14         d[b][a]=sqrt((v[a].first-v[b].first)*(v[a].first-v[b].first)+
15                      (v[a].second-v[b].second)*(v[a].second-v[b].second));
16     scanf("%d%d",&src,&dst);
17     for(k=1;k<=n;k++)
18         for(i=1;i<=n;i++)
19             for(j=1;j<=n;j++)
20                 d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
21     printf("%.2f\n",d[src][dst]);
22     return 0;
23 }

【代码2】Dijkstra算法O(n2

 1 #include <bits/stdc++.h>
 2 #define P pair<int,int>
 3 using namespace std;
 4 P ver[110];
 5 int n,m,i,j,src,dst,p1,p2;
 6 int v[110];
 7 double G[110][110],d[110];
 8 double calc(int a,int b)
 9 {
10     return sqrt((ver[a].first-ver[b].first)*(ver[a].first-ver[b].first)+
11                 (ver[a].second-ver[b].second)*(ver[a].second-ver[b].second));
12 }
13 void dijkstra()
14 {
15     int i,j,x;
16     memset(d,0x7f,sizeof(d));
17     d[src]=0;
18     for(i=1;i<n;i++) {
19         x=0;
20         for(j=1;j<=n;j++)
21             if(!v[j]&&(x==0||d[j]<d[x])) x=j;
22         v[x]=1;
23         for(j=1;j<=n;j++)
24             d[j]=min(d[j],d[x]+G[x][j]);
25     }
26 }
27 int main()
28 {
29     memset(G,0x7f,sizeof(G));
30     scanf("%d",&n);
31     for(i=1;i<=n;i++) scanf("%d%d",&ver[i].first,&ver[i].second);
32     scanf("%d",&m);
33     for(i=1;i<=m;i++) scanf("%d%d",&p1,&p2),G[p1][p2]=G[p2][p1]=calc(p1,p2); 
34     scanf("%d%d",&src,&dst);
35     dijkstra();
36     printf("%.2f\n",d[dst]);
37     return 0;
38 }

【代码3】Dijkstra算法堆优化 O((m+n)log(n))

 1 #include <bits/stdc++.h>
 2 #define P pair<int,int>
 3 using namespace std;
 4 struct edge{ int to,next; double val; }e[11000];
 5 int n,tot,m,a,b,src,dst,i;
 6 P ver[110];
 7 int head[110],v[110];
 8 double d[110];
 9 priority_queue< pair<double,int> >pq;
10 double calc(int a,int b)
11 {
12     return sqrt((ver[a].first-ver[b].first)*(ver[a].first-ver[b].first)
13                 +(ver[a].second-ver[b].second)*(ver[a].second-ver[b].second));
14 }
15 void add(int from,int to,double val)
16 {
17     e[++tot].to=to,e[tot].next=head[from];
18     head[from]=tot,e[tot].val=val;
19 }
20 void dijkstra()
21 {
22     memset(d,0x7f,sizeof(d));
23     d[src]=0.0;
24     pq.push(make_pair(0.0,src));
25     while(pq.size()) {
26         int x=pq.top().second; pq.pop();
27         if(v[x]) continue;
28         v[x]=1;
29         for(int i=head[x];i;i=e[i].next) {
30             int to=e[i].to;
31             double val=e[i].val;
32             if(d[to]>d[x]+val)
33                 d[to]=d[x]+val,pq.push(make_pair(-d[to],to));
34         }
35     }
36 }
37 int main()
38 {
39     scanf("%d",&n);
40     for(i=1;i<=n;i++) scanf("%d%d",&ver[i].first,&ver[i].second);
41     scanf("%d",&m);
42     for(i=1;i<=m;i++) scanf("%d%d",&a,&b),add(a,b,calc(a,b)),add(b,a,calc(a,b));
43     scanf("%d%d",&src,&dst);
44     dijkstra();
45     printf("%.2f\n",d[dst]);
46     return 0;
47 }

 

【代码4】Bellman-Ford算法 O(m*n)

 1 #include <bits/stdc++.h>
 2 #define P pair<int,int>
 3 using namespace std;
 4 struct edge{ int from,to; double val; }e[10010];
 5 P ver[110];
 6 int i,n,m,tot,a,b,src,dst,j;
 7 double d[110];
 8 int head[110];
 9 double calc(int a,int b)
10 {
11     return sqrt((ver[a].first-ver[b].first)*(ver[a].first-ver[b].first)+
12                 (ver[a].second-ver[b].second)*(ver[a].second-ver[b].second));
13 }
14 void add(int a,int b,double val)
15 {
16     e[++tot].from=a,e[tot].to=b,e[tot].val=val;
17 }
18 int main()
19 {
20     scanf("%d",&n);
21     for(i=1;i<=n;i++) scanf("%d%d",&ver[i].first,&ver[i].second);
22     scanf("%d",&m);
23     for(i=1;i<=m;i++) scanf("%d%d",&a,&b),add(a,b,calc(a,b)),add(b,a,calc(a,b));
24     scanf("%d%d",&src,&dst);
25     memset(d,0x7f,sizeof(d));
26     d[src]=0.0;
27     for(i=1;i<n;i++)
28         for(j=1;j<=tot;j++) {
29             int to=e[j].to,from=e[j].from;
30             d[to]=min(d[to],d[from]+e[j].val);
31         }
32     printf("%.2f\n",d[dst]);
33     return 0;
34 }

 

【代码5】Spfa(shortest path fast algorithm)O(km)k平均值为2

 1 #include <bits/stdc++.h>
 2 #define P pair<int,int>
 3 using namespace std;
 4 P ver[110];
 5 struct edge{ int to,next; double val; }e[10010];
 6 int n,m,i,src,dst,a,b,tot;
 7 int head[110],v[110];
 8 double d[110];
 9 queue<int> q;
10 double calc(int a,int b)
11 {
12     return sqrt((ver[a].first-ver[b].first)*(ver[a].first-ver[b].first)
13                 +(ver[a].second-ver[b].second)*(ver[a].second-ver[b].second));
14 }
15 void add(int from,int to,double val)
16 {
17     e[++tot].to=to,e[tot].next=head[from];
18     e[tot].val=val,head[from]=tot;
19 }
20 void spfa()
21 {
22     memset(d,0x7f,sizeof(d));
23     d[src]=0.0,v[src]=1;
24     q.push(src);
25     while(q.size()) {
26         int x=q.front(); q.pop();
27         v[x]=0;
28         for(int i=head[x];i;i=e[i].next) {
29             int to=e[i].to;
30             double val=e[i].val;
31             if(d[to]>d[x]+val) {
32                 d[to]=d[x]+val;
33                 if(!v[to]) q.push(to),v[to]=1;
34             }
35         }
36     }
37 }
38 int main()
39 {
40     scanf("%d",&n);
41     for(i=1;i<=n;i++) scanf("%d%d",&ver[i].first,&ver[i].second);
42     scanf("%d",&m);
43     for(i=1;i<=m;i++) scanf("%d%d",&a,&b),add(a,b,calc(a,b)),add(b,a,calc(a,b));
44     scanf("%d%d",&src,&dst);
45     spfa();
46     printf("%.2f\n",d[dst]);
47     return 0;
48 }

 

posted @ 2018-08-05 23:34  飞飞翔滴少年  阅读(659)  评论(0编辑  收藏  举报