zoukankan      html  css  js  c++  java
  • spfa + slf优化

    最近在练习费用流 , 不是要用spfa吗 ,我们教练说:ns学生写朴素的spfa说出去都让人笑 。

    QwQ,所以就去学了一下优化 。

    slf优化就是双向队列优化一下,本来想用lll优化,可是优化后我tm居然t了(那道题特地卡spfa),所以lll优化太迷了 ,还是只用slf优化好 。

     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <cstdio>
     5 #include <deque>
     6 const int inf = 1 << 30 , maxn = 100000 + 11 , M = 200000 + 11  ; 
     7 using namespace std ;//1061109567
     8 int n , m , head[maxn]  , dis[maxn] , cnt , sum , tot ;
     9 bool mark[maxn] ; 
    10 struct id
    11 {
    12     int nxt ,to , val ;
    13 } edge[M] ;
    14 deque < int > Q ;
    15 
    16 
    17 inline void Init ( )
    18 {
    19     freopen( "NSOOJ#10719.in" , "r" , stdin  ) ;
    20     freopen( "NSOOJ#10719.out" , "w" , stdout ) ;
    21 }
    22 
    23 int read( )
    24 {
    25     char ch = getchar( ) ; int k = 1 , ret = 0 ;
    26     while( ch < '0' || ch > '9' ) { if( ch == '-' ) k = -1 ; ch = getchar( ) ; }
    27     while( ch >= '0' && ch <= '9' ) ret = ret * 10 + ch - '0' , ch = getchar( ) ;
    28     return k * ret ;
    29 }
    30 
    31 void add( int u , int v , int va )
    32 {
    33     edge[++cnt].nxt = head[u] , edge[cnt].to = v ;
    34     edge[cnt].val = va , head[u] = cnt ;
    35 }
    36 
    37 void input(  )
    38 {
    39     n = read()  , m = read( ) ;
    40     int u ,v , c ;
    41     memset( head , -1 , sizeof(head)) ;
    42     for( int x = 1 ; x <= m ; ++x )
    43     {
    44         u = read( ) , v = read( ) , c = read( ) ;
    45         add( u ,v , c )  ;
    46     }
    47 }
    48 
    49 void spfa( )
    50 {
    51     memset( dis , 127/2 , sizeof(dis) ) ;
    52     dis[1] = 0 , mark[1] = true ;
    53     Q.push_back( 1 ) ;
    54     while( !Q.empty( ) )
    55     {
    56         int u = Q.front( ) ; Q.pop_front( ) ; mark[u] = false ;
    57     
    58         for( int i = head[u] ; ~i ; i = edge[i].nxt )
    59         {
    60             int v = edge[i].to ; 
    61             if( dis[v] > dis[u] + edge[i].val )
    62             {
    63                 dis[v] = dis[u] + edge[i].val ;
    64                 if( !mark[v] )
    65                 {
    66                     mark[v] = true ; 
    67                     if( Q.empty( ) || dis[v] > dis[Q.front( )]  ) Q.push_back( v ) ;
    68                     else Q.push_front( v ) ;
    69                     
    70                 }
    71             
    72             }
    73         }
    74     }
    75     if( dis[n] == 1061109567 ) printf( "%d
    " , -1 ) ;
    76     else printf( "%d
    " , dis[n] ) ;
    77 }
    78 
    79 
    80 int main( )
    81 {
    82 //    Init( ) ; 
    83     input( ) ;
    84     spfa( ) ;
    85 //    fclose( stdin ) ;
    86 //       fclose( stdout ) ;
    87     return 0 ;
    88 }

     纠正,其实lll优化一般效率还是挺高的,只是学长说如果要卡的话可以卡到指数级(=_=),所以下面是lll优化的代码 。 

     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <cstdio>
     5 #include <deque>
     6 const int inf = 1 << 30 , maxn = 100000 + 11 , M = 200000 + 11  ; 
     7 using namespace std ;//1061109567
     8 int n , m , head[maxn]  , dis[maxn] , cnt , sum , tot ;
     9 bool mark[maxn] ; 
    10 struct id
    11 {
    12     int nxt ,to , val ;
    13 } edge[M] ;
    14 deque < int > Q ;
    15 
    16 
    17 inline void Init ( )
    18 
    19 {
    20     freopen( "NSOOJ#10719.in" , "r" , stdin  ) ;
    21     freopen( "NSOOJ#10719.out" , "w" , stdout ) ;
    22 }
    23 
    24 int read( )
    25 {
    26     char ch = getchar( ) ; int k = 1 , ret = 0 ;
    27     while( ch < '0' || ch > '9' ) { if( ch == '-' ) k = -1 ; ch = getchar( ) ; }
    28     while( ch >= '0' && ch <= '9' ) ret = ret * 10 + ch - '0' , ch = getchar( ) ;
    29     return k * ret ;
    30 }
    31 
    32 void add( int u , int v , int va )
    33 {
    34     edge[++cnt].nxt = head[u] , edge[cnt].to = v ;
    35     edge[cnt].val = va , head[u] = cnt ;
    36 }
    37 
    38 void input(  )
    39 {
    40     n = read()  , m = read( ) ;
    41     int u ,v , c ;
    42     memset( head , -1 , sizeof(head)) ;
    43     for( int x = 1 ; x <= m ; ++x )
    44     {
    45         u = read( ) , v = read( ) , c = read( ) ;
    46         add( u ,v , c )  ;
    47     }
    48 }
    49 
    50 void spfa( )
    51 {
    52     memset( dis , 127/2 , sizeof(dis) ) ;
    53     dis[1] = 0 , mark[1] = true ;
    54     Q.push_back( 1 ) ; tot = 0 ;
    55     while( !Q.empty( ) )
    56     {
    57         int u = Q.front( ) ; Q.pop_front( ) ; mark[u] = false ;
    58         tot-- ; sum -= dis[u] ;
    59         for( int i = head[u] ; ~i ; i = edge[i].nxt )
    60         {
    61             int v = edge[i].to ; 
    62             if( dis[v] > dis[u] + edge[i].val )
    63             {
    64                 dis[v] = dis[u] + edge[i].val ;
    65                 if( !mark[v] )
    66                 {
    67                     mark[v] = true ; 
    68                     if( Q.empty( ) || dis[v] * tot <= sum ) Q.push_back( v ) ;
    69                     else Q.push_front( v ) ;
    70                     tot++ ; sum += dis[v] ;
    71                 }
    72             
    73             }
    74         }
    75     }
    76     if( dis[n] == 1061109567 ) printf( "%d
    " , -1 ) ;
    77     else printf( "%d
    " , dis[n] ) ;
    78 }
    79 
    80 
    81 int main( )
    82 {
    83 //    Init( ) ; 
    84     input( ) ;
    85     spfa( ) ;
    86 //    fclose( stdin ) ;
    87 //       fclose( stdout ) ;
    88     return 0 ;
    89 }

    好的,下面是两个都加的代码 。

     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <cstdio>
     5 #include <deque>
     6 const int inf = 1 << 30 , maxn = 100000 + 11 , M = 200000 + 11  ; 
     7 using namespace std ;//1061109567
     8 int n , m , head[maxn]  , dis[maxn] , cnt , sum , tot ;
     9 bool mark[maxn] ; 
    10 struct id
    11 {
    12     int nxt ,to , val ;
    13 } edge[M] ;
    14 deque < int > Q ;
    15 
    16 
    17 inline void Init ( )
    18 {
    19     freopen( "NSOOJ#10719.in" , "r" , stdin  ) ;
    20     freopen( "NSOOJ#10719.out" , "w" , stdout ) ;
    21 }
    22 
    23 int read( )
    24 {
    25     char ch = getchar( ) ; int k = 1 , ret = 0 ;
    26     while( ch < '0' || ch > '9' ) { if( ch == '-' ) k = -1 ; ch = getchar( ) ; }
    27     while( ch >= '0' && ch <= '9' ) ret = ret * 10 + ch - '0' , ch = getchar( ) ;
    28     return k * ret ;
    29 }
    30 
    31 void add( int u , int v , int va )
    32 {
    33     edge[++cnt].nxt = head[u] , edge[cnt].to = v ;
    34     edge[cnt].val = va , head[u] = cnt ;
    35 }
    36 
    37 void input(  )
    38 {
    39     n = read()  , m = read( ) ;
    40     int u ,v , c ;
    41     memset( head , -1 , sizeof(head)) ;
    42     for( int x = 1 ; x <= m ; ++x )
    43     {
    44         u = read( ) , v = read( ) , c = read( ) ;
    45         add( u ,v , c )  ;
    46     }
    47 }
    48 
    49 void spfa( )
    50 {
    51     memset( dis , 127/2 , sizeof(dis) ) ;
    52     dis[1] = 0 , mark[1] = true ;
    53     Q.push_back( 1 ) ; tot = 1 ;
    54     while( !Q.empty( ) )
    55     {
    56         int u = Q.front( ) ; Q.pop_front( ) ; mark[u] = false ;
    57         tot-- ; sum -= dis[u] ;
    58         for( int i = head[u] ; ~i ; i = edge[i].nxt )
    59         {
    60             int v = edge[i].to ; 
    61             if( dis[v] > dis[u] + edge[i].val )
    62             {
    63                 dis[v] = dis[u] + edge[i].val ;
    64                 if( !mark[v] )
    65                 {
    66                     mark[v] = true ; 
    67                     if( Q.empty( ) || dis[v] > dis[Q.front( )] || dis[v] * tot <= sum ) Q.push_back( v ) ;
    68                     else Q.push_front( v ) ;
    69                     tot++ ; sum += dis[v] ;
    70                 }
    71             
    72             }
    73         }
    74     }
    75     if( dis[n] == 1061109567 ) printf( "%d
    " , -1 ) ;
    76     else printf( "%d
    " , dis[n] ) ;
    77 }
    78 
    79 
    80 int main( )
    81 {
    82 //    Init( ) ; 
    83     input( ) ;
    84     spfa( ) ;
    85 //    fclose( stdin ) ;
    86 //       fclose( stdout ) ;
    87     return 0 ;
    88 }
  • 相关阅读:
    Android测试工具 UIAutomator入门与介绍
    C#异步编程
    懒得找,存个笔记:easyui combogrid 下拉+关键字搜索
    mssql replace
    序列化类型为XX的对象时检测到循环引用
    shell脚本运行python命令
    python技巧
    边缘检测测评标准
    mybatis 手动生成可执行sql
    Linux如何扩容物理文件系统分区
  • 原文地址:https://www.cnblogs.com/Ateisti/p/5937832.html
Copyright © 2011-2022 走看看