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

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

#include 
#include 
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int n,m;
int head[10005];
vector > 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_queueq;
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 
#include 
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int n,m;
int head[10005];
//vector > 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_queueq;
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;
    }
}

你可能感兴趣的:(算法)