使用最小堆dijk求最短路径的标准算法,时间复杂度为elogv。
#include
<
cstdio
>
#include
<
string
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#define
INF 2000000000
#define
MAXN 500000
#define
MAXM 500000
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
T, N, M;
int
dist[MAXN], next[
2
][MAXM], num[
2
][MAXN], heap[MAXN], idx[MAXN], used[MAXN];
int
size, src, dst;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
typedef
struct
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int u, v, w;
}
Edge;
Edge e[
2
][MAXM];
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
update (
int
);
int
get_top ();
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
printHeap ()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int i;
for ( i = 1; i <= size; i ++ )
printf ( "%d ", heap[i] );
printf ( " " );
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
id ()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int i;
for ( i = 0; i <= N; i ++ )
dist[i] = INF;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
init ()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
scanf ( "%d%d", &N, &M );
memset ( num, 0x00, sizeof ( num ) );
memset ( idx, 0x00, sizeof ( idx ) );
memset ( used, 0x00, sizeof ( used ) );
int i, x, y, w;
// 链表存储
for ( i = 1; i <= M; i ++ )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
scanf ( "%d%d%d", &x, &y, &w );
e[0][i].u = x, e[0][i].v = y, e[0][i].w = w;
e[1][i].u = y, e[1][i].v = x, e[1][i].w = w;
next[0][i] = num[0][x], num[0][x] = i, next[1][i] = num[1][y], num[1][y] = i;
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
dijk ()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int ans = 0;
// 两次dijk,求对于点1,出路径和返回路径最短
id ();
size = 0, src = 1;
dist[src] = 0, used[src] = 1, heap[++ size] = 1, idx[src] = 1;
int i;
while ( true )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if ( size == 0 )
break;
int u, v;
u = get_top ();
used[u] = 1;
for ( i = num[0][u]; i; i = next[0][i] )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
v = e[0][i].v;
if ( !used[v] && dist[v] > dist[u] + e[0][i].w )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if ( idx[v] == 0 )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
heap[++ size] = v;
idx[v] = size;
}
dist[v] = dist[u] + e[0][i].w;
update ( v );
}
}
}
for ( i = 2; i <= N; i ++ )
ans += dist[i];
id ();
memset ( used, 0x00, sizeof ( used ) );
memset ( idx, 0x00, sizeof ( idx ) );
size = 0, src = 1;
dist[src] = 0, used[src] = 1, heap[++ size] = 1, idx[src] = 1;
while ( true )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if ( size == 0 )
break;
int u, v;
u = get_top ();
used[u] = 1;
for ( i = num[1][u]; i; i = next[1][i] )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
v = e[1][i].v;
if ( !used[v] && dist[v] > dist[u] + e[1][i].w )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if ( idx[v] == 0 )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
heap[++ size] = v;
idx[v] = size;
}
dist[v] = dist[u] + e[1][i].w;
update ( v );
}
}
}
for ( i = 2; i <= N; i ++ )
ans += dist[i];
return ans;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
main ()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
//freopen ( "in.txt", "r", stdin );
scanf ( "%d", &T );
int i;
for ( i = 0; i < T; i ++ )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
init ();
printf ( "%d ", dijk () );
}
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
get_top ()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int ret = heap[1];
int p = 1, q = 2, r = heap[size --]; //p 当前点 q 父节点,下同
while ( q <= size )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if ( q < size && dist[heap[q]] > dist[heap[q + 1]] )
q ++;
if ( dist[r] > dist[heap[q]] )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
idx[heap[q]] = p;
heap[p] = heap[q];
p = q, q <<= 1;
}
else
break;
}
idx[r] = p, heap[p] = r;
return ret;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
update (
int
r )
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int q = idx[r], p = q >> 1;
while ( p && dist[r] < dist[heap[p]] )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
heap[q] = heap[p], idx[heap[p]] = q;
q = q >> 1, p = p >> 1;
}
heap[q] = r, idx[r] = q;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)