zoukankan      html  css  js  c++  java
  • 最短路径问题(信息学奥赛一本通 1342)

    【题目描述】

    平面上有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


    1.Floyed-Warshall算法 O(N3)   n<=500

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int a[101][3], n,i,j,k,x,y,m,s,e;
     4 double f[101][101];
     5 int main()
     6 {
     7     cin >> n;
     8     for (i = 1; i <= n; i++)
     9         cin >> a[i][1] >> a[i][2];                //第i个点的坐标
    10     cin >> m;
    11     memset(f,0x3f,sizeof(f));                 //初始化f数组为最大值
    12    for (i = 1; i <= m; i++)                            //预处理出x、y间距离
    13     {
    14       cin >> x >> y;    //pow(x,y)表示x^y,其中x,y必须为double类型,要用cmath库
    15       f[y][x] = f[x][y] = sqrt(pow(double(a[x][1]-a[y][1]),2)+pow(double(a[x][2]-a[y][2]),2));     
    16     }
    17     cin >> s >> e;
    18     for (k = 1; k <= n; k++)                     //floyed 最短路算法
    19        for (i = 1; i <= n; i++)
    20           for (j = 1; j <= n; j++)
    21              if ((i != j) && (i != k) && (j != k) && (f[i][k]+f[k][j] < f[i][j]))
    22                  f[i][j] = f[i][k] + f[k][j];
    23     printf("%.2lf
    ",f[s][e]);
    24     return 0;  
    25 }

     2.Dijkstra算法O (N2)   未优化n<=5000    贪心

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int a[101][3] ,f[101][101];;
     4 double c[101];
     5 bool b[101];
     6 int n,i,j,k,x,y,m,s,e;
     7 double minl;
     8 double maxx = 1e30;
     9 int main()
    10 {
    11     cin >> n;
    12     for (i = 1; i <= n; i++)
    13       cin >> a[i][1] >> a[i][2];
    14     for (i = 1; i <= n; i++)
    15       for(j = 1; j <= n; j++)
    16         f[i][j] = maxx;                         //f数组初始化最大值
    17     cin >> m;
    18     for (i = 1; i <= m; i++)                    //预处理x.y间距离f[x][y]
    19     {
    20         cin >> x >> y;
    21         f[x][y] = f[y][x] = sqrt(pow(double(a[x][1]-a[y][1]),2)+pow(double(a[x][2]-a[y][2]),2));
    22     }
    23     cin >> s >> e;
    24     for (i = 1; i <= n; i++) 
    25       c[i] = f[s][i];                            //初始化
    26     memset(b,false,sizeof(b));      //dijkstra 最短路
    27     b[s] = true;                                //源点
    28     c[s] = 0; 
    29     for (i = 1; i <= n-1; i++)
    30     {
    31         minl = maxx;                        //贪心找最小
    32         k = 0;
    33         for (j = 1; j <= n; j++)     //查找可以更新的点
    34            if ((! b[j]) && (c[j] < minl))
    35             {
    36                 minl = c[j];
    37                 k = j;
    38             }
    39         if (k == e) break;     //小优化
    40         b[k] = true;
    41         for (j = 1; j <= n; j++)
    42            if (c[k] + f[k][j] < c[j]) 
    43              c[j] = c[k] + f[k][j];
    44     }    
    45    printf("%.2lf
    ",c[e]);
    46    return 0;
    47 }

    堆优化后Dijkstra算法O (NlogN) 

     for (i = 1; i <= n-1; i++)
        {
            minl = maxx;
            k = 0;
            for (j = 1; j <= n; j++) //查找可以更新的点
               if ((! b[j]) && (c[j] < minl))
                {
                    minl = c[j];
                    k = j;
                }
            if (k == e) break;
            b[k] = true;
            for (j = 1; j <= n; j++)
               if (c[k] + f[k][j] < c[j]) 
                 c[j] = c[k] + f[k][j];
        }    

    邻接表加堆优化

    也可以另定一个函数

    3.Bellman-Ford算法O(NE)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int main()
     4 {
     5     double a[101][3],dis[1001],w[1001],min1;
     6     int n,m,x,y,k,f[1001][3],s,t;  //  f数组储存第i条边的起点与终点
     7     bool b[101];
     8     cin>>n;
     9     for (int i=1;i<=n;i++) 
    10        scanf("%lf%lf",&a[i][1],&a[i][2]);
    11     cin>>m;
    12     for (int i=1;i<=m;i++)                       //初始化数组dis
    13        dis[i]=0x7fffffff/3;
    14  for (int i=1;i<=m;i++)
    15     {
    16         scanf("%d%d",&x,&y);
    17         f[i][1]=x; f[i][2]=y;
    18         w[i]=sqrt(pow(a[x][1]-a[y][1],2)+pow(a[x][2]-a[y][2],2));
    19     }
    20     cin>>s>>t;
    21     dis[s]=0; 
    22     for (int i=1;i<=n;i++) //ford算法主体
    23        for (int j=1;j<=m;j++)
    24        {
    25           if (dis[f[j][1]]+w[j]<dis[f[j][2]]) dis[f[j][2]]=dis[f[j][1]]+w[j];
    26           if (dis[f[j][2]]+w[j]<dis[f[j][1]]) dis[f[j][1]]=dis[f[j][2]]+w[j];
    27        }
    28     printf("%.2f",dis[t]);
    29 }

    4、SPFA算法O(kE)

  • 相关阅读:
    博客推荐
    oracle11g dataguard 安装手册(转)
    Linux文件系统介绍(转)
    降低磁盘IO使Oracle性能优化(转)
    关于AWR报告命中率指标的解释(转)
    oracle 锁的介绍 (转)
    oracle undo redo 解析
    oracle sqlplus 连接不正常
    Oracle技术嘉年华
    断线的回忆
  • 原文地址:https://www.cnblogs.com/ljy-endl/p/11266426.html
Copyright © 2011-2022 走看看