zoukankan      html  css  js  c++  java
  • 最短路径问题8595

    最短路径问题8595

    问题描述

    平面上有n个点(n<=100),每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。

    若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点间的直线距离。现在的任务是找出从一点到另一点之间的最短路径。

    输入文件

    共n+m+3行,其中:

    第一行为整数n。
    第2行到第n+1行(共n行) ,每行两个整数x和y,描述了一个点的坐标。
    第n+2行为一个整数m,表示图中连线的个数。
    此后的m 行,每行描述一条连线,由两个整数i和j组成,表示第i个点和第j个点之间有连线。
    最后一行:两个整数s和t,分别表示源点和目标点。

    输出

    仅一行,一个实数(保留两位小数),表示从s到t的最短路径长度。

    样例输入

    5 0 0 2 0 2 2 0 2 3 1 5 1 2 1 3 1 4 2 5 3 5 1 5

    样例输出

    3.41

    题解

    一道不折不扣的大水题…(所以我为什么要写水题呢…?当然是熟悉下博客功能……)

    首先是一个尴尬的问题,两点间距离公式。忘掉了?戳->http://t.cn/Efz0mN8

    这里采用的是floyed算法。(什么是floyed?戳->https://www.cnblogs.com/Uninstalllingyi/p/10417446.html)

    需要注意的只是初始化问题和数据类型、小数位数保留问题。总之问题不大。

     1 #include<iostream>
     2 #include<cmath>
     3 #include<cstring>
     4 //floyed
     5 using namespace std;
     6 const int MAXN=101;
     7 double map[MAXN][MAXN];
     8 struct position{
     9     int x;
    10     int y;
    11 }pos[MAXN];
    12 double dist(int a,int b){
    13     double ans;
    14     double x=pos[a].x-pos[b].x;
    15     double y=pos[a].y-pos[b].y;
    16     ans=sqrt(x*x+y*y);
    17     return ans;
    18 }
    19 int main(){
    20     int n;
    21     cin>>n;
    22     for(int i=1;i<=n;i++){
    23         cin>>pos[i].x>>pos[i].y;
    24     }
    25     int m;
    26     cin>>m;
    27     memset(map,127,sizeof(map));
    28     int p1,p2;
    29     for(int i=1;i<=m;i++){
    30         cin>>p1>>p2;
    31         map[p1][p2]=map[p2][p1]=dist(p1,p2);
    32     }
    33     cin>>p1>>p2;//我实在是懒得再开变量了…
    34 for(int k=1;k<=n;k++){
    35     for(int i=1;i<=n;i++){
    36         for(int j=1;j<=n;j++){
    37             if(i!=k&&i!=j&&j!=k){
    38                 map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
    39             }
    40         }
    41     }
    42 }    
    43     printf("%.2f",map[p1][p2]); 
    44 }
    View Code

     然后逐渐发现floyed算法并不够优秀。

     1 #include<iostream>
     2 #include<cmath>
     3 #include<cstring>
     4 using namespace std;
     5 //Bellman-Ford
     6 const int MAXN=105;
     7 struct edge{
     8     int s,e;
     9     double w;
    10 }edges[MAXN*(MAXN-1)/2];
    11 int n,m,idx;
    12 double dis[MAXN],map[MAXN][2];
    13 void addedge(int u,int v,double w){
    14     edges[++idx].s=u;edges[idx].e=v;edges[idx].w=w;
    15     edges[++idx].s=v;edges[idx].e=u;edges[idx].w=w;
    16 }
    17 double dist(int a,int b){
    18     double x=map[a][0]-map[b][0];
    19     double y=map[a][1]-map[b][1];
    20     return sqrt(x*x+y*y);
    21 }
    22 void bellman(){
    23     while(--n){
    24         bool b=0;
    25         for(int i=1;i<=idx;i++){
    26             if(dis[edges[i].e]>dis[edges[i].s]+edges[i].w){
    27                 dis[edges[i].e]=dis[edges[i].s]+edges[i].w;
    28                 b=1;
    29             }
    30         }
    31         if(!b){
    32             break;
    33         }
    34     }
    35 }
    36 int main(){
    37     cin>>n;
    38     for(int i=1;i<=n;i++){
    39         cin>>map[i][0]>>map[i][1];
    40     }
    41     cin>>m;
    42     int a,b;
    43     for(int i=1;i<=m;i++){
    44         cin>>a>>b;
    45         addedge(a,b,dist(a,b));
    46     }
    47     int s,e;
    48     cin>>s>>e;
    49     for(int i=1;i<=n;i++){
    50         dis[i]=0x3f3f3f3f;
    51     }
    52     dis[s]=0;
    53     bellman();
    54     printf("%.2f
    ",dis[e]);
    55 }
    View Code

    所以来了一波福特算法。

    然后发觉还不够过瘾,

     1 #include<iostream>
     2 #include<cmath>
     3 #include<cstring>
     4 using namespace std;
     5 const int MAXN=500;
     6 const double maxx=1e18;
     7 double minx;
     8 //dijkstra
     9 double map[MAXN][MAXN];
    10 int point[MAXN][3];
    11 bool vis[MAXN];
    12 double dis[MAXN];
    13 double dist(int a,int b){
    14     double ans;
    15     double x=point[a][1]-point[b][1];
    16     double y=point[a][2]-point[b][2];
    17     ans=sqrt(x*x+y*y);
    18     return ans;
    19 }
    20 int main(){
    21     memset(map,0x7f,sizeof(map));
    22     int n;
    23     cin>>n;
    24     int x,y;
    25     for(int i=1;i<=n;i++){
    26         cin>>point[i][1]>>point[i][2];
    27     }
    28     int m;
    29     cin>>m;
    30     for(int i=1;i<=m;i++){
    31         cin>>x>>y;
    32         map[x][y]=map[y][x]=dist(x,y);
    33     }
    34     int s,t;
    35     cin>>s>>t;
    36     for(int i=1;i<=n;i++){
    37         dis[i]=map[s][i];
    38     }
    39     vis[s]=true;dis[s]=0;
    40     for(int i=1,k=0;i<=n-1;i++){
    41         minx=maxx;
    42         for(int j=1;j<=n;j++){
    43             if(!vis[j]&&dis[j]<minx){
    44                 minx=dis[j];
    45                 k=j;
    46             }
    47         }
    48         if(k==0){
    49             break;
    50         }
    51         vis[k]=true;
    52         for(int j=1;j<=n;j++){
    53             dis[j]=min(dis[j],dis[k]+map[k][j]);
    54         }
    55     }
    56     printf("%.2lf",dis[t]);
    57 }
    View Code

    dijkstra算法。

    这些算法都在本博里有作介绍。(目前跑得最快的是福特)

  • 相关阅读:
    ORBSLAM2的资源
    工程思想
    Linux中PATH、 LIBRARY_PATH、 LD_LIBRARY_PATH和ROS_PACKAGE_PATH
    CMkeList文件编写
    SLAM资料
    windows下隐藏文件夹
    Ubuntu16装Flash
    知识管理
    学习纲领
    lsof详解
  • 原文地址:https://www.cnblogs.com/Uninstalllingyi/p/10417756.html
Copyright © 2011-2022 走看看