好久没写博客了,最近忙于期末考试复习,所以更的就少了,今天总结一下最短路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;
}
}