zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ", dist[n][1]);
    91     }
    92     return 0;
    93 }

    优化了速度就是不一样!

  • 相关阅读:
    OOAD-2 UML建模、类、接口、类图的详细介绍
    OOAD-1 GOF中的23种设计模式的分类和功能
    java核心技术第四章疑问点
    数据结构中的遇到的一些小知识整理
    springboot中一次坑爹的打包体验
    mybatis中@param的使用与否
    mybatis 防止sql注入
    java窗口
    java异常处理
    第三次上级作业
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4717859.html
Copyright © 2011-2022 走看看