zoukankan      html  css  js  c++  java
  • 弗洛伊德算法(Floyd)

    此算法可以求任意两点的最短距离,其中边权值可以为负数,而dijkstra只能是固定的点间的距离,并且边全值不能为负数。

    保存的是后面的点(更好)

    #include<iostream>
    #include<stdio.h>
    #include<iomanip>
    using namespace std;
    #define N 100
    #define MAX 1000000
    int a[N][N];
    int path[N][N];
    void input (int n)
    {
     int p,q,len,i,j;
     for( i=1;i<=n;i++)
      for(j=1;j<=n;j++)
      {
       a[i][j]=MAX;
       if(i==j)
        a[i][j]=0;
      }
     while(1)
     {
      cin>>p>>q;
      if(p||q)
       cin>>len;
      else
       break;
      a[p][q]=len;
     }
    }
    void Floyd(int n)
    {
     int i,j,k;
     for(i=1;i<=n;i++)
      for(j=1;j<=n;j++)
       path[i][j]=j;//初始化路径,将i后面的点记录在path中
     for(k=1;k<=n;k++)
      for(i=1;i<=n;i++)
       for(j=1;j<=n;j++)
        if(a[i][j]>a[i][k]+a[k][j])
        {
         a[i][j]=a[i][k]+a[k][j];
         path[i][j]=path[i][k];/*path记录i后面的点*/
        }
     printf("最短路径矩阵如下:\n");
     for(i=1;i<=n;i++)/*打印最短路径矩阵j*/
     {
      for(j=1;j<=n;j++)
       printf("%8d",a[i][j]);
      cout<<endl;
     }
    }
    void Dispath(int n)//输出经过的点
    {
     int i,j,h;
     for(i=1;i<=n;i++)
      for(j=1;j<=n;j++)
      {
             cout<<" 点 "<<i<<" 到点 "<<j<<" 最短长度为: "<<a[i][j];
       cout<<" 经过的点为:  ";
                cout<<i<<"->";
             h=path[i][j];
             while(h!=j)
       {
                 cout<<h<<"->";
              h=path[h][j];
       }
             cout<<j<<endl;
      }
    }   
    int main()
    {
     int n;
     scanf("%d",&n);
     input(n);
     Floyd(n);
     Dispath(n);
     return 0;
    }
    或者

    保存的是前面的点

    #include<iostream>
    #include<stdio.h>
    #include<iomanip>
    using namespace std;
    #define N 100
    #define MAX 10000
    int a[N][N];
    int path[N][N];
    void input (int n)
    {
     int p,q,len,i,j;
     for( i=1;i<=n;i++)
      for(j=1;j<=n;j++)
      {
       a[i][j]=MAX;
       if(i==j)
        a[i][j]=0;
      }
     while(1)
     {
      cin>>p>>q;
      if(p||q)
       cin>>len;
      else
       break;
      a[p][q]=len;
     }
    }
    void Floyd(int n)
    {
     int i,j,k;
     for(i=1;i<=n;i++)
      for(j=1;j<=n;j++)
       path[i][j]=i;//初始化路径,将j前面的点记录在path中
     for(k=1;k<=n;k++)
      for(i=1;i<=n;i++)
       for(j=1;j<=n;j++)
        if(a[i][j]>a[i][k]+a[k][j])
        {
         a[i][j]=a[i][k]+a[k][j];
         path[i][j]=path[k][j];/*path记录j前面的点*/
        }
     printf("最短路径矩阵如下:\n");
     for(i=1;i<=n;i++)/*打印最短路径矩阵*/
     {
      for(j=1;j<=n;j++)
       printf("%8d",a[i][j]);
      cout<<endl;
     }
    }
    void Dispath(int n)//输出经过的点
    {
     int i,j,temp,que[N],tot;
     for(i=1;i<=n;i++)
      for(j=1;j<=n;j++)
      {
       tot=1;
       que[tot++]=j;
       temp=path[i][j];
       while(temp!=i)
       {
        que[tot++]=temp;
        temp=path[i][temp];
       }
       que[tot]=i;
       cout<<" 点 "<<i<<" 到点 "<<j<<" 最短长度为: "<<a[i][j];
       cout<<" 经过的点为:  ";
       for(;tot>1;tot--)
        cout<<que[tot]<<"->";
       cout<<que[tot]<<endl;
      }
    }   
    int main()
    {
     int n;
     scanf("%d",&n);
     input(n);
     Floyd(n);
     Dispath(n);
     return 0;
    }
    递归也可以

    #include<iostream>
    #include<stdio.h>
    #include<iomanip>
    using namespace std;
    #define N 100
    #define MAX 10000
    int a[N][N];
    int path[N][N];
    void input (int n)
    {
     int p,q,len,i,j;
     for( i=1;i<=n;i++)
      for(j=1;j<=n;j++)
      {
       a[i][j]=MAX;
       if(i==j)
        a[i][j]=0;
      }
     while(1)
     {
      cin>>p>>q;
      if(p||q)
       cin>>len;
      else
       break;
      a[p][q]=len;
     }
    }
    void Floyd(int n)
    {
     int i,j,k;
     for(i=1;i<=n;i++)
      for(j=1;j<=n;j++)
       path[i][j]=-1;
     for(k=1;k<=n;k++)
      for(i=1;i<=n;i++)
       for(j=1;j<=n;j++)
        if(a[i][j]>a[i][k]+a[k][j])
        {
         a[i][j]=a[i][k]+a[k][j];
         path[i][j]=k;
        }
     printf("最短路径矩阵如下:\n");
     for(i=1;i<=n;i++)/*打印最短路径矩阵*/
     {
      for(j=1;j<=n;j++)
       printf("%8d",a[i][j]);
      cout<<endl;
     }
    }
    void ppath(int i,int j)//递归你懂吗
    {
     int k;
     k=path[i][j];
     if(k==-1)
      return;
     ppath(i,k);
     printf("->%d",k);
     ppath(k,j);
    }
    void Dispath(int n)//输出经过的点
    {
     int i,j;
     for(i=1;i<=n;i++)
      for(j=1;j<=n;j++)
      {
       cout<<" 点 "<<i<<" 到点 "<<j<<" 最短长度为: "<<a[i][j];
       cout<<" 经过的点为:  ";
       cout<<i;
       ppath(i,j);
       cout<<"->"<<j;
       cout<<endl;
      }
    }   
    int main()
    {
     int n;
     scanf("%d",&n);
     input(n);
     Floyd(n);
     Dispath(n);
     return 0;
    }

  • 相关阅读:
    spring加载bean实例化顺序
    Java生成CSV文件实例详解
    JSch
    socket(一)
    Core Data
    运行时c函数
    ReactiveCocoa(RAC)
    先来个xmpp学习连接
    FMDB
    NSKeyedArchive(存储自定义对象)
  • 原文地址:https://www.cnblogs.com/heqinghui/p/2611906.html
Copyright © 2011-2022 走看看