如果std::vector<vector<pair<int,int> > > v(n)
代表pair<int,int>
对{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);
}
}
ans[i]
存储初始化为{LLONG_MAX,...0,...LLONG_MAX}
的最短路径,0
为源。由于这是我第一次尝试实现它,有没有更好的方法来实现使用stl中的vectors / list(可能在时间/空间复杂度方面)?
答案 0 :(得分:0)
当前的方法有逻辑错误(在迭代时修改向量)。 同样复杂性似乎非常糟糕,因为冗余的while循环每次获得新的最小距离节点和不必要的擦除操作,由于整个邻接列表的移位而导致向量很大。
我建议使用优先级队列&lt; min heap&gt;,它更清晰,复杂度为Elog(N),其中E为no。边缘和N没有。图中的节点。 我只是复制粘贴我的一个旧代码和评论。
#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 ));
}
}
}
如果您有任何疑问,请随时在评论中提问。
答案 1 :(得分:0)
优化Dijkstra的一些方法:
理论上,Dijkstra可以用Fibonacci堆优化到O(E + VlogV)。但实际上它的工作速度较慢。