基于邻接矩阵的Dijkstra和基于优先队列的Dijkstra算法

//有环图求最短路问题
//基于邻接矩阵的Dijkstra算法
//基于优先队列的Dijkstra算法
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
//思路:从一个节点到另外一个节点的最短路一定有中间节点贡献中间边,添加这些中间边比较发现最短路


//基于邻接矩阵的Dijkstra算法
const int maxn=10000;
int G[maxn][maxn];
int done[maxn],d[maxn];
int n,begin,end;
void Dijkstra(){
    memset(done,0,sizeof(done));
    for(int i=0;i<n;i++)
        i==begin?d[i]=0:d[i]=0x3f3f3f3f;
    
    for(int i=0;i<n;i++){//迭代n次取到每个节点
        int x,y=0x3f3f3f3f;
        for(int z=0;z<n;z++)if(!done[z]&&d[z]<=y)
            y=d[x=z];
        done[x]=1;
        for(int z=0;z<n;z++){//观察x到z节点添加了x到z的边之后能不能让z到起点的距离变小
            d[z]=min(d[z],d[x]+G[x][z]);
        }
    }
}
int main(){
    cout<<"The nodes and edges"<<endl;
    cin>>n>>m;
    cout<<"The begin and the end"<<endl;
    cin>>begin>>end;
    cout<<"The Graph"<<endl;
    memset(G,0x3f3f3f3f,sizeof(G));
    for(int i=0;i<m;i++){
        int a,b;
        cin>>a>>b>>G[a][b];
        G[b][a]=G[a][b];
    }
    Dijkstra();
    for(int i=0;i<n;i++)printf("%d ",d[i]);
    return 0;

}


//基于优先队列的Dijkstra算法

//基于优先队列的Dijkstra算法
//思路:添加x到y的一条边看能够让 to节点到起点的距离更近;即是松弛操作
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=10000;
int n,m,beg,end1;
struct Node{
    int from,to,len;
};
struct Edge{//这个必须要,保证每次在没有被访问过的节点中找到最小d[i]
    int d,u;
    bool operator <(const Edge& rhs)const{
        return d>rhs.d;
    }
};
vector<Node> node;
vector<int>  G[maxn];
int v[maxn],d[maxn];
void Dijkstra(){
    memset(v,0,sizeof(v));
    for(int i=0;i<n;i++)
        i==beg?d[i]=0:d[i]=0x3f3f3f3f;
    priority_queue<Edge> que;
    que.push(Edge{0,beg});
    while(que.size()){
        Edge e=que.top();que.pop();
        printf("%d %d Test\n",e.d,e.u);
        if(v[e.u])continue;
        v[e.u]=1;
        for(int i=0;i<G[e.u].size();i++){
            Node nd=node[G[e.u][i]];
            if(d[nd.to]>d[nd.from]+nd.len){
                d[nd.to]=d[nd.from]+nd.len;
                que.push(Edge{d[nd.to],nd.to});//取d[i]最小的
            }
        }
    }
}
int main(){
    cout<<"The n nodes and m edges,begin and end"<<endl;
    cin>>n>>m>>beg>>end1;
    cout<<"The m edges"<<endl;
    for(int i=0;i<m;i++){
        int x,y,w;
        cin>>x>>y>>w;
        node.push_back(Node{x,y,w});
        G[x].push_back(node.size()-1);
    }
//    cout<<G[0][0]<<" "<<G[0][1]<<" "<<G[1][0]<<" "<<G[2][0]<<endl;
    Dijkstra();
    for(int i=0;i<n;i++)printf("%d ",d[i]);
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值