poj 3255 dijstra求次短路

无负权边,所以可以用dijstra来求次短路,过程和求最短路一样,反复揣摩求次短路的过程有助于更深入的理解dijstra。

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

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6 
 7 const int INF = 9999999;
 8 const int N = 5001;
 9 const int M = 200000;
10 int head[N];
11 int dist[N][2];
12 bool visit[N][2];
13 int n, m, e;
14 
15 struct Edge
16 {
17     int v, next, w;
18 } edge[M];
19 
20 void addEdge( int u, int v, int w )
21 {
22     edge[e].v = v;
23     edge[e].w = w;
24     edge[e].next = head[u];
25     head[u] = e++;
26 }
27 
28 void dij( int s )
29 {
30     memset( visit, false, sizeof(visit) );
31     memset( dist, 0x3f, sizeof(dist) );
32     dist[s][0] = 0;
33     for ( int i = 1; i <= 2 * n; i++ )
34     {
35         int u, flag, mincost = INF;
36         for ( int j = 1; j <= n; j++ )
37         {
38             for ( int k = 0; k <= 1; k++ )
39             {
40                 if ( !visit[j][k] && dist[j][k] < mincost )
41                 {
42                     mincost = dist[j][k];
43                     u = j;
44                     flag = k;
45                 }
46             }
47         }
48         visit[u][flag] = 1;
49         for ( int j = head[u]; j != -1; j = edge[j].next )
50         {
51             int v = edge[j].v, w = edge[j].w;
52             if ( !visit[v][0] && dist[v][0] > dist[u][flag] + w )
53             {
54                 dist[v][1] = dist[v][0];
55                 dist[v][0] = dist[u][flag] + w;
56             }
57             else if ( !visit[v][1] && dist[v][1] > dist[u][flag] + w )
58             {
59                 dist[v][1] = dist[u][flag] + w;
60             }
61         }
62     }
63 }
64 
65 int main ()
66 {
67     while ( scanf("%d%d", &n, &m) != EOF )
68     {
69         e = 0;
70         memset( head, -1, sizeof(head) );
71         while ( m-- )
72         {
73             int u, v, w;
74             scanf("%d%d%d", &u, &v, &w);
75             addEdge( u, v, w );
76             addEdge( v, u, w );
77         }
78         dij(1);
79         printf("%d\n", dist[n][1]);
80     }
81     return 0;
82 }

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

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <queue>
 6 using namespace std;
 7 
 8 const int INF = 9999999;
 9 const int N = 5001;
10 const int M = 200000;
11 int head[N];
12 int dist[N][2];
13 bool visit[N][2];
14 int n, m, e;
15 
16 struct Edge
17 {
18     int v, next, w;
19 } edge[M];
20 
21 void addEdge( int u, int v, int w )
22 {
23     edge[e].v = v;
24     edge[e].w = w;
25     edge[e].next = head[u];
26     head[u] = e++;
27 }
28 
29 struct Node 
30 {
31     int nn, tt, len;
32     Node(){}
33     Node( int _nn, int _tt, int _len )
34     {
35         nn = _nn, tt = _tt, len = _len;
36     }
37     bool operator < ( const Node & o ) const 
38     {
39         return len > o.len;   
40     }
41 };
42 
43 priority_queue<Node> q;
44 
45 void dij( int s )
46 {
47     memset( visit, 0, sizeof(visit) );
48     memset( dist, 0x3f, sizeof(dist) );
49     dist[s][0] = 0;
50     q.push( Node( s, 0, 0 ) );
51     while ( !q.empty() )
52     {
53         Node cur = q.top();
54         q.pop();
55         if ( visit[cur.nn][cur.tt] ) continue;
56         visit[cur.nn][cur.tt] = true;
57         for ( int i = head[cur.nn]; i != -1; i = edge[i].next )
58         {
59             int v = edge[i].v, w = edge[i].w;
60             if ( !visit[v][0] && cur.len + w < dist[v][0] )
61             {
62                 dist[v][1] = dist[v][0];
63                 dist[v][0] = cur.len + w;
64                 q.push( Node( v, 1, dist[v][1] ) );
65                 q.push( Node( v, 0, dist[v][0] ) );
66             }
67             else if ( !visit[v][1] && cur.len + w < dist[v][1] )
68             {
69                 dist[v][1] = cur.len + w;
70                 q.push( Node( v, 1, dist[v][1] ) );
71             }
72         }    
73     }
74 }
75 
76 int main ()
77 {
78     while ( scanf("%d%d", &n, &m) != EOF )
79     {
80         e = 0;
81         memset( head, -1, sizeof(head) );
82         while ( m-- )
83         {
84             int u, v, w;
85             scanf("%d%d%d", &u, &v, &w);
86             addEdge( u, v, w );
87             addEdge( v, u, w );
88         }
89         dij(1);
90         printf("%d\n", dist[n][1]);
91     }
92     return 0;
93 }

优化了速度就是不一样!

posted @ 2015-08-10 14:07  hxy_has_been_used  阅读(191)  评论(0编辑  收藏  举报