最短路径问题

图——基本的图算法(五)最短路径_图论

BFS算法

图——基本的图算法(五)最短路径_最短距离_02

图——基本的图算法(五)最短路径_#include_03图——基本的图算法(五)最短路径_i++_04
完整代码

#include <iostream>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
#define NaN 0xFFFFFFF //定义一个最大值
const int vertexnum=8;//顶点数
int vertexList[vertexnum]={1,2,3,4,5,6,7,8};//顶点表
int AdjMatrix[vertexnum][vertexnum];//邻接矩阵
void AdjInitilazition()//无向图
{
  for(int i=0;i<vertexnum;i++)
    for(int j=0;j<vertexnum;j++)
      AdjMatrix[i][j]=0;
  AdjMatrix[0][1]=AdjMatrix[1][0]=1;
  AdjMatrix[0][4]=AdjMatrix[4][0]=1;
  AdjMatrix[1][5]=AdjMatrix[5][1]=1;
  AdjMatrix[5][2]=AdjMatrix[2][5]=1;
  AdjMatrix[5][6]=AdjMatrix[6][5]=1;
  AdjMatrix[3][6]=AdjMatrix[6][3]=1;
  AdjMatrix[2][3]=AdjMatrix[3][2]=1;
  AdjMatrix[6][3]=AdjMatrix[3][6]=1;
  AdjMatrix[6][7]=AdjMatrix[7][6]=1;
  AdjMatrix[3][7]=AdjMatrix[7][3]=1;
}    
bool visited[vertexnum];
int d[vertexnum];//d[i]:记录源顶点v到顶点i的距离
int path[vertexnum];//path[i]:顶点i的前驱节点
queue<int>Q;
void DFS(int v)
{
  for(int i=0;i<vertexnum;i++)
  {
    d[i]=NaN;
    path[i]=-1;
  }
  visited[v]=true;
  d[v]=0;
  Q.push(v);
  while(!Q.empty())
  {
    v=Q.front();
    Q.pop();
    for(int i=0;i<vertexnum;i++)
      if(!visited[i] && AdjMatrix[v][i])
      {
        d[i]=d[v]+1;
        path[i]=v;
        visited[i]=true;
        Q.push(i);
      }
  }
}
void MinusPath_DFS(int v,int j)
{
  DFS(v);
  int temp=j;
  while(path[temp]!=-1)
    temp=path[temp];
  if(temp==v)
    printf("顶点%d到顶点%d的最短距离为:%d\n",vertexList[v],vertexList[j],d[j]);
  else 
    printf("顶点%d到顶点%d之间不连通\n");
}

测试

int main()
{
  AdjInitilazition();
  MinusPath_DFS(1,7);//求顶点2和顶点8之间的最短路径
}

运行结果

顶点2到顶点8的最短距离为:3

Dijkstra算法

图——基本的图算法(五)最短路径_#include_05
图——基本的图算法(五)最短路径_#include_06
图——基本的图算法(五)最短路径_#include_07
图——基本的图算法(五)最短路径_最短距离_08
图——基本的图算法(五)最短路径_#include_09
图——基本的图算法(五)最短路径_i++_10
完整代码

#include <iostream>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
#define NaN 0xFFFFFFF //定义一个最大值
const int vertexnum=5;//顶点数
string vertexList[vertexnum]={"V0","V1","V2","V3","V4"};//顶点表
int AdjMatrix[vertexnum][vertexnum];//邻接矩阵
void AdjInitilazition()//有向带权图
{
  for(int i=0;i<vertexnum;i++)
    for(int j=0;j<vertexnum;j++)
      AdjMatrix[i][j]=NaN;
  AdjMatrix[0][1]=10;
  AdjMatrix[0][4]=5;
  AdjMatrix[1][4]=2;
  AdjMatrix[4][1]=3;
  AdjMatrix[1][2]=1;
  AdjMatrix[4][2]=9;
  AdjMatrix[4][3]=2;
  AdjMatrix[3][0]=7;
  AdjMatrix[2][3]=4;
  AdjMatrix[3][2]=6;
}    
bool visited[vertexnum];
int dis[vertexnum];//d[i]:记录源顶点v到顶点i的距离
int path[vertexnum];//path[i]:顶点i的前驱节点
bool cmp(int i,int j)
{
  return i<j;
}
int findminus()
{
  int min=NaN;
  int res=-1;
  for(int i=0;i<vertexnum;i++)
  {
    if(!visited[i] && dis[i]<min)
    {
      min=dis[i];
      res=i;
    }
  }
  return res;
}
void Dijkstra(int v)
{
  for(int i=0;i<vertexnum;i++)//初始化
  {
    visited[i]=false;
    dis[i]=AdjMatrix[v][i];
    path[i]=dis[i]==NaN?-1:v;
  }
  int cnt=1;
  while(cnt<vertexnum)
  {
    int k=findminus();
    visited[k]=true;
    for(int i=0;i<vertexnum;i++)
    {
      if(!visited[i] && dis[k]+AdjMatrix[k][i]<dis[i])
        dis[i]=dis[k]+AdjMatrix[k][i];
    }
    cnt++;
  }
}
void MinusPath_Dijkstra(int v1,int v2)
{
  Dijkstra(v1);
  printf("点%s到点%s的最短距离为:%d\n",vertexList[v1].c_str(),vertexList[v2].c_str(),dis[v2]);
}

测试`

int main()
{
  AdjInitilazition();
  MinusPath_Dijkstra(0,2);
  MinusPath_Dijkstra(0,3);
}

运行结果

点V0到点V2的最短距离为:9
点V0到点V3的最短距离为:7

Floyd算法

图——基本的图算法(五)最短路径_最短距离_11
图——基本的图算法(五)最短路径_图论_12
图——基本的图算法(五)最短路径_i++_13
图——基本的图算法(五)最短路径_i++_14
图——基本的图算法(五)最短路径_图论_15
图——基本的图算法(五)最短路径_最短距离_16
图——基本的图算法(五)最短路径_最短路径_17
图——基本的图算法(五)最短路径_最短路径_18
图——基本的图算法(五)最短路径_图论_19
核心代码

#include <iostream>
#include <stack>
#include <queue>
#include <vector>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
#define NaN 0xFFFFFFF //定义一个最大值
const int vertexnum=5;//顶点数
string vertexList[vertexnum]={"V0","V1","V2","V3","V4"};//顶点表
int AdjMatrix[vertexnum][vertexnum];//邻接矩阵
void AdjInitilazition()//有向带权图
{
  for(int i=0;i<vertexnum;i++)
    for(int j=0;j<vertexnum;j++)
      AdjMatrix[i][j]=NaN;
  AdjMatrix[0][2]=1;
  AdjMatrix[0][4]=10;
  AdjMatrix[1][4]=5;
  AdjMatrix[1][3]=1;
  AdjMatrix[2][1]=1;
  AdjMatrix[2][4]=7;
  AdjMatrix[3][4]=1;
}    
int A[vertexnum][vertexnum];
int Path[vertexnum][vertexnum];
void MinusPath_Floyd()
{
  for(int i=0;i<vertexnum;i++)
    for(int j=0;j<vertexnum;j++){
      A[i][j]=AdjMatrix[i][j];//初始化
      Path[i][j]=-1;
    }
    
  for(int k=0;k<vertexnum;k++)//Floyd算法核心代码
    for(int i=0;i<vertexnum;i++)
      for(int j=0;j<vertexnum;j++)
        if(A[i][k]+A[k][j]<A[i][j]){
          A[i][j]=A[i][k]+A[k][j];
          Path[i][j]=k;
        }
          
}

测试

void display(int i)
{
  if(i==NaN)
    printf("N  ");
  else 
    printf("%d  ",i);
}

void displayMidPoint(int i,int j,vector<int>&V)
{
  if(Path[i][j]!=-1)
  {
    auto it=find(V.begin(),V.end(),j);
    V.insert(it,Path[i][j]);
    displayMidPoint(i,Path[i][j],V);
    displayMidPoint(Path[i][j],j,V);
  }
}
void displayPath(int i,int j)
{
  vector<int>V;
  printf("点%s到点%s的最短路径为:%s-->",vertexList[i].c_str(),vertexList[j].c_str(),vertexList[i].c_str());
  displayMidPoint(i,j,V);
  for(int k:V)
    printf("%s-->",vertexList[k].c_str());
  printf("%s\n",vertexList[j].c_str());
}
int main()
{
  AdjInitilazition();
  MinusPath_Floyd();
  printf("   ");
  for(int i=0;i<vertexnum;i++)
    printf(" %s",vertexList[i].c_str());
  printf("\n");
  for(int i=0;i<vertexnum;i++)
  {
    printf("%s: ",vertexList[i].c_str());
    for(int j=0;j<vertexnum;j++)
      display(A[i][j]);
    printf("\n");
  }
  displayPath(0,4);
  
}

运行结果

    V0 V1 V2 V3 V4
V0: N  2  1  3  4  
V1: N  N  N  1  2  
V2: N  1  N  2  3  
V3: N  N  N  N  1  
V4: N  N  N  N  N  
点V0到点V4的最短路径为:V0-->V2-->V1-->V3-->V4