您的位置:首页 > Web前端 > JavaScript

poj 3255 dijstra求次短路

2015-08-10 14:07 579 查看
无负权边,所以可以用dijstra来求次短路,过程和求最短路一样,反复揣摩求次短路的过程有助于更深入的理解dijstra。

O(n^2)的写法(500ms):

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int INF = 9999999;
const int N = 5001;
const int M = 200000;
int head
;
int dist
[2];
bool visit
[2];
int n, m, e;

struct Edge
{
int v, next, w;
} edge[M];

void addEdge( int u, int v, int w )
{
edge[e].v = v;
edge[e].w = w;
edge[e].next = head[u];
head[u] = e++;
}

void dij( int s )
{
memset( visit, false, sizeof(visit) );
memset( dist, 0x3f, sizeof(dist) );
dist[s][0] = 0;
for ( int i = 1; i <= 2 * n; i++ )
{
int u, flag, mincost = INF;
for ( int j = 1; j <= n; j++ )
{
for ( int k = 0; k <= 1; k++ )
{
if ( !visit[j][k] && dist[j][k] < mincost )
{
mincost = dist[j][k];
u = j;
flag = k;
}
}
}
visit[u][flag] = 1;
for ( int j = head[u]; j != -1; j = edge[j].next )
{
int v = edge[j].v, w = edge[j].w;
if ( !visit[v][0] && dist[v][0] > dist[u][flag] + w )
{
dist[v][1] = dist[v][0];
dist[v][0] = dist[u][flag] + w;
}
else if ( !visit[v][1] && dist[v][1] > dist[u][flag] + w )
{
dist[v][1] = dist[u][flag] + w;
}
}
}
}

int main ()
{
while ( scanf("%d%d", &n, &m) != EOF )
{
e = 0;
memset( head, -1, sizeof(head) );
while ( m-- )
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
addEdge( u, v, w );
addEdge( v, u, w );
}
dij(1);
printf("%d\n", dist
[1]);
}
return 0;
}


优先队列优化的写法(110ms):

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;

const int INF = 9999999;
const int N = 5001;
const int M = 200000;
int head
;
int dist
[2];
bool visit
[2];
int n, m, e;

struct Edge
{
int v, next, w;
} edge[M];

void addEdge( int u, int v, int w )
{
edge[e].v = v;
edge[e].w = w;
edge[e].next = head[u];
head[u] = e++;
}

struct Node
{
int nn, tt, len;
Node(){}
Node( int _nn, int _tt, int _len )
{
nn = _nn, tt = _tt, len = _len;
}
bool operator < ( const Node & o ) const
{
return len > o.len;
}
};

priority_queue<Node> q;

void dij( int s )
{
memset( visit, 0, sizeof(visit) );
memset( dist, 0x3f, sizeof(dist) );
dist[s][0] = 0;
q.push( Node( s, 0, 0 ) );
while ( !q.empty() )
{
Node cur = q.top();
q.pop();
if ( visit[cur.nn][cur.tt] ) continue;
visit[cur.nn][cur.tt] = true;
for ( int i = head[cur.nn]; i != -1; i = edge[i].next )
{
int v = edge[i].v, w = edge[i].w;
if ( !visit[v][0] && cur.len + w < dist[v][0] )
{
dist[v][1] = dist[v][0];
dist[v][0] = cur.len + w;
q.push( Node( v, 1, dist[v][1] ) );
q.push( Node( v, 0, dist[v][0] ) );
}
else if ( !visit[v][1] && cur.len + w < dist[v][1] )
{
dist[v][1] = cur.len + w;
q.push( Node( v, 1, dist[v][1] ) );
}
}
}
}

int main ()
{
while ( scanf("%d%d", &n, &m) != EOF )
{
e = 0;
memset( head, -1, sizeof(head) );
while ( m-- )
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
addEdge( u, v, w );
addEdge( v, u, w );
}
dij(1);
printf("%d\n", dist
[1]);
}
return 0;
}


优化了速度就是不一样!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: