【题目描述】
平面上有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 ",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 ",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 ",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 ",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 ",d[dst]); 47 return 0; 48 }