数据结构------最短路径Dijkstra和最小生成树Prim

prim和Dijkstra算法主要是在d数组上面的含义不同,对于prim的d数组是d[i]是i节点到最小生成树结合的距离,而Dijkstra的d数组则是i节点到目标节点s的距离。

最短路径并用path并查集数组来记录路径节点信息

#include <bits/stdc++.h>
#define maxv 1000
#define INF 99999
using namespace std;
int n,m,s;/*n个顶点、m条边、s为起点*/
int path[maxv];/*一个并查集数组*/
int G[maxv][maxv];
int d[maxv];/*d[i]代表着第i个节点到目标节点s的距离*/
bool  vis[maxv]={false};
int findfater(int x){
    int index=x;
    int temp[100];
    int top=0;
    temp[top++]=x;
     while(path[x]!=x){
           //cout<<x<<' ';
           x=path[x];
           temp[top++]=x;
     }
     //temp[top++]=x;
     for(int i=top-1;i>=0;i--){
        if(d[index]==INF){
            cout<<s<<"  不可达  "<<i;
            break;
        }
        else if(d[index]==0){
             cout<<"自身节点";
             break;
        }
        if(i!=0){
            cout<<temp[i]<<"-->";
        }else{
            cout<<temp[i]<<"\t\t路径长度为"<<d[index];
        }
     }
     cout<<endl;
}
int initpath(int n){
    for(int i=0;i<n;i++){
          path[i]=i;
    }
}
void InitG(){
   for(int i=0;i<maxv;i++){
      for(int j=0;j<maxv;j++){
            G[i][j]=INF;
      }
   }
}
/*m为目标节点*/
void  Dijkstra(int s,int n){
   initpath(n);
   //path[s]=s;//并查集初始化
   fill(d,d+maxv,INF);
   d[s]=0;
   for(int i=0;i<n;i++){
        int u=-1,Min=INF;
        for(int j=0;j<n;j++){
             if(vis[j]==false&&d[j]<Min){
                  u=j;
                  Min=d[j];
             }
        }
        if(u==-1){
            return ;
        }
        vis[u]=true;
        for(int v=0;v<n;v++){
            if(vis[v]==false&&G[u][v]!=INF&&G[u][v]+d[u]<d[v]){
                  d[v]=G[u][v]+d[u];
                  path[v]=u;
            }
        }
   }
}
int main()
{

     cout<<"请输入顶点数和边数:"<<endl;
     cin>>n>>m>>s;
     int u,v,weight;
     InitG();/*初始化全部为INF*/
     for(int i=0;i<m;i++){
          cin>>u>>v>>weight;
          if(weight<G[u][v]){/*防止这个两个顶点之间存在多条边*/
                G[u][v]=weight;
          }
     }
    Dijkstra(s,n);
    for(int i=0;i<n;i++){
        findfater(i);
    }

    return 0;
}
/*6个顶点 8条边 以0号节点为例子
6 8 1
0 1 1
0 3 4
0 4 4
1 3 2
2 5 1
3 2 2
3 4 3
4 5 3
0 1 5 3 4 6
*/

Prim算法

#include <bits/stdc++.h>
#define maxv 1000
#define INF 99999
using namespace std;
int G[maxv][maxv];
int d[maxv];/*d[i]代表着第i个节点到结合S的距离*/
bool  vis[maxv]={false};
void InitG(){
   for(int i=0;i<maxv;i++){
      for(int j=0;j<maxv;j++){
            G[i][j]=INF;
      }
   }

}
int prim(int n){
   int ans=0;
   fill(d,d+maxv,INF);
   d[0]=0;
   for(int i=0;i<n;i++){/*最外层循环是遍历每一个顶点*/
        int u=-1,Min=INF;
        for(int j=0;j<n;j++){
             if(vis[j]==false&&d[j]<Min){
                  u=j;
                  Min=d[j];
             }
        }
        if(u==-1){
            return -1;
        }
        vis[u]=true;
        ans+=d[u];
        for(int v=0;v<n;v++){
            if(vis[v]==false&&G[u][v]!=INF&&G[u][v]<d[v]){
                  d[v]=G[u][v];
            }
        }
   }
   return ans;

}
int main()
{
     int n,m;
     cout<<"请输入顶点数和边数:"<<endl;
     cin>>n>>m;
     int u,v,weight;
     InitG();/*初始化全部为INF*/
     for(int i=0;i<m;i++){
          cin>>u>>v>>weight;
          if(weight<G[u][v]){
                G[v][u]=G[u][v]=weight;
          }
     }
    cout<<prim(n);
    return 0;
}
/*
6 10
0 1 4
0 4 1
0 5 2
1 2 6
1 5 3
2 3 6
2 5 5
3 4 4
3 5 5
4 5 3
结果为15
*/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

坏牧羊人.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值