dijkstra 加上堆优化及两种存储图的方法

好久没写博客了,最近忙于期末考试复习,所以更的就少了,今天总结一下最短路Dijkstra算法的堆优化的思想及代码,加上几种存图的方法临接表和vector加上pair<int,int>,都是从别人那里学来的,嘿嘿,大佬别喷啊。
首先附上vector的代码:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int n,m;
int head[10005];
vector<pair<int,int> > A[10005];
int ans;
int dis[10005];
bool vis[10005];
struct Node{
    int id;
    int s;
    Node(){};
    Node(int _id,int _s):id(_id),s(_s){};
    bool operator < (const Node & rhs)const//这里在优先队列里存Node必须重载<来达到弹出最大值的目的。
    {
        return s > rhs.s;//没次把队列里长度最长的节点给弹出来。
    }
};
/*void Addedge(int from,int to,int value)
{
    A[ans].to = to;
    A[ans].value = value;
    A[ans].next = head[from];
    head[from] = ans++;
}*/
priority_queue<Node>q;
void Dijkstra(int x)
{
    memset(dis,INF,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[x] = 0;//原点出发。
    q.push(Node(x,0));
    while(!q.empty())
    {
        int st = q.top().id;
        int ex = q.top().s;
        q.pop();
        if(vis[st]) continue;//走过就直接跳过。
        vis[st] = 1;
        for(int i = 0;i < A[st].size();i++)
        {
            int to = A[st][i].first;
            int s = A[st][i].second;
            if(dis[to] > ex + s && vis[to] == 0)
            {
                dis[to] = dis[st] + s;
                q.push(Node(to,dis[to]));
            }
        }
    }
}
int main()
{
    cin >> n >> m;
    for(int i = 1;i <= n;i++)A[i].clear();
    for(int i = 1;i <= m;i++)
    {
        int x,y,z;
        cin >> x >> y >> z;
        A[x].push_back(make_pair(y,z));
        A[y].push_back(make_pair(x,z));
    }
    Dijkstra(1);
    for(int i = 1;i <= n;i++)
    {
        cout << dis[i] << endl;
    }
}
接下来是临接表存图的代码:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int n,m;
int head[10005];
//vector<pair<int,int> > A[10005];
int ans;
int dis[10005];
bool vis[10005];
struct Road{
    int to,w,next;
}A[10005];
struct Node{
    int id;
    int s;
    Node(){};
    Node(int _id,int _s):id(_id),s(_s){};
    bool operator < (const Node & rhs)const
    {
        return s > rhs.s;//没次把队列里长度最长的节点给弹出来。
    }
};
void Addedge(int from,int to,int value)
{
    A[ans].to = to;
    A[ans].w = value;
    A[ans].next = head[from];
    head[from] = ans++;
}
priority_queue<Node>q;
void Dijkstra(int x)
{
    memset(dis,INF,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[x] = 0;
    q.push(Node(x,0));
    while(!q.empty())
    {
        int st = q.top().id;
        //int ex = q.top().s;
        q.pop();
        if(vis[st]) continue;
        vis[st] = 1;
        for(int i = head[st];i != -1;i = A[i].next)
        {
            int to = A[i].to;
            int s = A[i].w;
            if(dis[to] > dis[st] + s && vis[to] == 0)
            {
                dis[to] = dis[st] + s;
                q.push(Node(to,dis[to]));
            }
        }
    }
}
int main()
{
    cin >> n >> m;
    //for(int i = 1;i <= n;i++)A[i].clear();
    memset(head, -1,sizeof(head));//注意这里初始化链表的时候一定写在道路输入前。
    for(int i = 1;i <= m;i++)
    {
        int x,y,z;
        cin >> x >> y >> z;
        Addedge(x,y,z);
        Addedge(y,x,z);
        /*A[x].push_back(make_pair(y,z));
        A[y].push_back(make_pair(x,z));*/
    }
    Dijkstra(1);
    for(int i = 1;i <= n;i++)
    {
        cout << dis[i] << endl;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值