图的最短路径-升级版

//这个版本使用了huilu数组存放这个点的前一个合理点;
//while( no_s(v-1,s) )//当所求的点不在s中,这语句严格来说是求点(v-1)这个点到始点的路径
//for(i=0;i<v;++i)//这条语句能求所有点的最短路径
//前两句也适应前版本
///粘贴输入下列
4 4
0 1 1
0 3 1
0 2 3

2 3 4

#include <iostream>
using namespace std;
//012345分别表示v0 v1......
  int v;//点数目
  int edge;///边数目
  int si=0;//si用来控制s数组的位置

int** draw();//绘图
int no_s_l_min(int* s,int* l);//不在s数组中的l数组中最小的点
int no_s(int k,int* s);//不在s数组中的
void digui_shuchu(int k,int *huilu);//递归输出
int main(int argc, char const *argv[])
{
  int i;
  int**a=draw();
//------------------------------------------------------------------------//
  int* s=new int[v];//存放ok了的标记,si用来控制s数组的位置
  for ( i = 0; i < v; ++i)s[i]=32767;
//------------------------------------------------------------------------//
  int* l=new int[v];//存放i点到0点的路径长度
  for ( i = 0; i < v; ++i)l[i]=32767;
//------------------------------------------------------------------------//
  int* huilu=new int[v];//存放i点的前一个合理点
  for ( i = 0; i < v; ++i)huilu[i]=-1;
//------------------------------------------------------------------------//
l[0]=0;
 int u;//不属于s的并且l【u】最小的一个顶点
  huilu[0]=0;
//------------------------------------------------------------------------//
  while( no_s(v-1,s) )//当所求的点不在s中
  {
    u=no_s_l_min(s,l);
    s[si++]=u;
    for ( i = 0; i < v; ++i)
    {
       if (no_s(i,s) && a[u][i]<32767 && i!=u)
       {
         if (l[u]+a[u][i] < l[i])//lenth和路径将会改变
         {/更换i的所有数据            
           l[i]=l[u]+a[u][i];
           huilu[i]=u;
         }
       }
    }
  }
//------------------------------------------------------------------------//
    cout<<"0";
  digui_shuchu(v-1,huilu);
  return 0;
}
int** draw()//绘图
{
  int i,j;
  cin>>v>>edge;///输入点数目和边数目
  int **a=new int*[v];
  for ( i = 0; i < v; ++i)
    a[i]=new int[v];
  for ( i = 0; i < v; ++i)
    for ( j = 0; j < v; ++j)
      a[i][j]=32767;

  int spot1,spot2,len;
  for ( i = 0; i < edge; ++i)
  {
    cin>>spot1>>spot2>>len;
    a[spot1][spot2]=len;    a[spot2][spot1]=len;
  }
///-------------------------------------------------------------///
    for ( i = 0; i < v; ++i){
    for ( j = 0; j < v; ++j)
      cout<<a[i][j]<<" ";
    cout<<"\n";
    }
    cout<<"\n";
  return a;
}
int no_s_l_min(int* s,int *l)//不再s数组中的l数组中最小的点
{
  int mark=0;
  int min;
     for (int i = 0; i < v; ++i)
     {
       if(no_s(i,s) )//不在s数组里的点vi
        {
          if(mark==0){min=i;mark=1;}//必然会执行一次,初始化min
          else
          {
            if (l[min] > l[i])
              min=i;         
          }
        }
     }
     return min;//返回Vmin;
}
int no_s(int k,int* s)
{
  for (int i = 0; i <= si; ++i)
    if(s[i]==k)return 0;//点vk不再s[i]中
 return 1;
}
void digui_shuchu(int k,int *huilu)
{
  if (k!=0)
  {
  digui_shuchu(huilu[k],huilu);
  cout<<k;
  }
  else return;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

紫云的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值