C++ 最有效地实施Dijkstra';在C++;stl
如果C++ 最有效地实施Dijkstra';在C++;stl,c++,algorithm,vector,stl,dijkstra,C++,Algorithm,Vector,Stl,Dijkstra,如果std::vector v(n)表示图的邻接列表,而pair是{vertex,weight}对,则我尝试以下方式实现该算法: while (true) { long long yo = LLONG_MAX; int ind = -1; for (int i = 0; i < n; ++i) { if (ans[i] < yo && !v[i].empty()) { ind =
std::vector v(n)
表示图的邻接列表,而pair
是{vertex,weight}
对,则我尝试以下方式实现该算法:
while (true)
{
long long yo = LLONG_MAX;
int ind = -1;
for (int i = 0; i < n; ++i)
{
if (ans[i] < yo && !v[i].empty())
{
ind = i;
yo = ans[i];
}
}
if (ind == -1)
break;
for (int i = 0; i < v[ind].size(); ++i)
{
if (ans[v[ind][i].first] > ans[ind] + v[ind][i].second)
ans[v[ind][i].first] = ans[ind] + v[ind][i].second;
v[ind].erase(v[ind].begin() + i);
}
}
while(true)
{
long long yo=LLONG_MAX;
int ind=-1;
对于(int i=0;ians[ind]+v[ind][i].second)
ans[v[ind][i]。第一]=ans[ind]+v[ind][i]。第二;
v[ind].erase(v[ind].begin()+i);
}
}
其中,
ans[i]
存储初始化为{LLONG_MAX,…0,…LLONG_MAX}
,0
作为源的最短路径。由于这是我第一次尝试实现它,有没有更好的方法在stl中使用向量/列表来实现(可能在时间/空间复杂性方面)?当前方法存在逻辑缺陷(在迭代向量时修改向量)。
同样从复杂性的角度来看,它看起来也很糟糕,因为每次都会重复while循环以获得新的最小距离节点,并且不需要执行擦除操作,由于整个邻接列表的移动,该操作的向量很重
我建议使用优先级队列#define P first
#define Q second
typedef long long LL ;
typedef pair < LL , int > li ;
typedef pair < int , LL > il ;
dist[N] = {INT_MAX} ; // array containing the distance to each node from source node
vector < il > adj [100010] ; // adjacency list with (node, distance) pair
void dijkstra( int s ){ // s is the source node
priority_queue < li , vector < li > , greater < li > > pq; // priortiy queue with a pair <long, int> as the data , using vector as underlying data structure and std:greater comparator
dist [s] = 0;
pq.push( li( dist[s], s) );
while( !pq.empty() ){
li u = pq.top() ; pq.pop() ; // u.P = current minimum distance of node , u.Q = current node on top of the heap
if( dist[u.Q] == u.P )
for( int i = 0 ; i < adj[u.Q].size() ; i++){
il v = adj[u.Q][i] ;
if( dist[v.P] > u.P + v.Q ){
dist[v.P] = u.P + v.Q ;
pq.push( li(dis[v.P] ,v.P ));
}
}
}
#首先定义P
#定义Q秒
typedef long-long-LL;
typedef对li;
typedef对il;
dist[N]={INT_MAX};//包含每个节点到源节点的距离的数组
向量adj[100010];//具有(节点、距离)对的邻接列表
void dijkstra(int s){//s是源节点
优先级队列,更大的 >pq;//使用向量作为底层数据结构和std:greater comparator的一对作为数据的优先级队列
距离[s]=0;
质量推送(li(距离[s],s));
而(!pq.empty()){
li u=pq.top();pq.pop();//u.P=节点的当前最小距离,u.Q=堆顶部的当前节点
如果(距离[u.Q]==u.P)
对于(int i=0;iu.P+v.Q){
dist[v.P]=u.P+v.Q;
质量推送(li(dis[v.P],v.P));
}
}
}
如果您有任何问题,请随时发表评论。一些优化Dijkstra的方法:
#define P first
#define Q second
typedef long long LL ;
typedef pair < LL , int > li ;
typedef pair < int , LL > il ;
dist[N] = {INT_MAX} ; // array containing the distance to each node from source node
vector < il > adj [100010] ; // adjacency list with (node, distance) pair
void dijkstra( int s ){ // s is the source node
priority_queue < li , vector < li > , greater < li > > pq; // priortiy queue with a pair <long, int> as the data , using vector as underlying data structure and std:greater comparator
dist [s] = 0;
pq.push( li( dist[s], s) );
while( !pq.empty() ){
li u = pq.top() ; pq.pop() ; // u.P = current minimum distance of node , u.Q = current node on top of the heap
if( dist[u.Q] == u.P )
for( int i = 0 ; i < adj[u.Q].size() ; i++){
il v = adj[u.Q][i] ;
if( dist[v.P] > u.P + v.Q ){
dist[v.P] = u.P + v.Q ;
pq.push( li(dis[v.P] ,v.P ));
}
}
}
理论上,Dijkstra可以用Fibonacci堆优化为O(E+VlogV)。但实际上它的工作速度较慢。这个问题可能更适合,因为它似乎是关于已经工作的代码。“更好”在什么方面?速度?内存使用?我个人最看重可读性;)@tobi303时间和内存usage@yobro97如果您想使用向量向量优化时间和内存使用,则已经失败。我认为
v[ind].erase(v[ind].begin()+I);
是错误的(因为您在向量的迭代过程中以一种奇怪的方式修改了向量)。