赞
踩
观察dijkstradijkstra的流程,发现步骤22可以优化
怎么优化呢?
我会zkw线段树!我会斐波那契堆!
我会堆!
我们可以用堆对disdis数组进行维护,用O(\log_{2}n)O(log2n)的时间取出堆顶元素并删除,用O(\log_{2}n)O(log2n)遍历每条边,总复杂度O((n+m)\log_{2}n)O((n+m)log2n)
范例代码:
-
- #include<bits/stdc++.h>
-
- const int MaxN = 100010, MaxM = 500010;
-
- struct edge
- {
- int to, dis, next;
- };
-
- edge e[MaxM];
- int head[MaxN], dis[MaxN], cnt;
- bool vis[MaxN];
- int n, m, s;
-
- inline void add_edge( int u, int v, int d )
- {
- cnt++;
- e[cnt].dis = d;
- e[cnt].to = v;
- e[cnt].next = head[u];
- head[u] = cnt;
- }
-
- struct node
- {
- int dis;
- int pos;
- bool operator <( const node &x )const
- {
- return x.dis < dis;
- }
- };
-
- std::priority_queue<node> q;
-
-
- inline void dijkstra()
- {
- dis[s] = 0;
- q.push( ( node ){0, s} );
- while( !q.empty() )
- {
- node tmp = q.top();
- q.pop();
- int x = tmp.pos, d = tmp.dis;
- if( vis[x] )
- continue;
- vis[x] = 1;
- for( int i = head[x]; i; i = e[i].next )
- {
- int y = e[i].to;
- if( dis[y] > dis[x] + e[i].dis )
- {
- dis[y] = dis[x] + e[i].dis;
- if( !vis[y] )
- {
- q.push( ( node ){dis[y], y} );
- }
- }
- }
- }
- }
-
-
- int main()
- {
- scanf( "%d%d%d", &n, &m, &s );
- for(int i = 1; i <= n; ++i)dis[i] = 0x7fffffff;
- for( register int i = 0; i < m; ++i )
- {
- register int u, v, d;
- scanf( "%d%d%d", &u, &v, &d );
- add_edge( u, v, d );
- }
- dijkstra();
- for( int i = 1; i <= n; i++ )
- printf( "%d ", dis[i] );
- return 0;
- }
-
-
-
下一章讲弱化版,也就是洛谷【P3371】单源最短路径(弱化版)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。