美文网首页信息学竞赛题解(IO题解)
BZOJ-1003: [ZJOI2006]物流运输trans(D

BZOJ-1003: [ZJOI2006]物流运输trans(D

作者: AmadeusChan | 来源:发表于2018-10-16 20:29 被阅读0次

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1003

刚开始看题目有点晕,盯了vfleaking大神的题解(Orz)半天之后猛然觉悟,然后猛敲一顿SPFA+DP,1次水过。。。

代码:


fcfaaf51f3deb48f4e935aa9f21f3a292cf578cb.jpg.png
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <deque>
 
using namespace std ;
 
#define MAXN 110
#define MAXM 30
#define inf ( 1 << 20 )
 
int n , m ;
 
struct graph {
        struct edge {
               edge *next ;
               int t , d ; 
        } *head[ MAXM ] ;
        
        graph (  ) {
               memset( head , 0 , sizeof( head ) ) ;
        }
        
        void Add( int s ,int t ,int d ) {
               edge *p = new( edge ) ;
               p -> t = t , p -> d = d , p -> next = head[ s ] ; 
               head[ s ] = p ;
        }
        void AddEdge( int s , int t , int d ) {
               Add( s , t , d ) , Add( t , s , d ) ;
        }
        
        bool flag[ MAXM ] , f[ MAXM ] , va[ MAXM ][ MAXN ] ;
        int dist[ MAXM ] ;
        deque< int > Q ;
        
        int spfa(  ) {
               for ( int i = 0 ; i ++ < m ; ) f[ i ] = false , dist[ i ] = inf ;
               long long sum = 0 ; Q.clear(  ) ;
               dist[ 1 ] = 0 , f[ 1 ] = true , Q.push_back( 1 ) ;
               while ( ! Q.empty(  ) ) {
                       while ( dist[ Q.front(  ) ] > sum / Q.size(  ) + 1 ) Q.push_back( Q.front(  ) ) , Q.pop_front(  ) ;
                       int v = Q.front(  ) ; Q.pop_front(  ) ;
                       f[ v ] = false , sum -= dist[ v ] ;
                       for ( edge *p = head[ v ] ; p ; p = p -> next ) if ( flag[ p -> t ] && dist[ p -> t ] > dist[ v ] + p -> d ) {
                               if ( f[ p -> t ] ) sum -= dist[ p -> t ] ;
                               sum += ( dist[ p -> t ] = dist[ v ] + p -> d ) ;
                               if ( ! f[ p -> t ] ) {
                                      f[ p -> t ] = true ;
                                      if ( Q.empty(  ) ) Q.push_back( p -> t ) ; else if ( dist[ p -> t ] < dist[ Q.front(  ) ] ) Q.push_front( p -> t ) ; else Q.push_back( p -> t ) ;
                               }
                       }
               }
               return dist[ m ] ;
        }
        
        int cost( int l , int r ) {
               memset( flag , true , sizeof( flag ) ) ;
               for ( int i = 0 ; i ++ < m ; ) for ( int j = l ; j <= r ; j ++ ) if ( ! va[ i ][ j ] ) {
                       flag[ i ] = false ; break ;
               }
               return spfa(  ) ;
        }
} g ;
 
int dp[ MAXN ] , k , e , d ;
 
int main(  ) {
        memset( g.va , true , sizeof( g.va ) ) ;
        scanf( "%d%d%d%d" , &n , &m , &k , &e ) ;
        while ( e -- ) {
               int s , t , v ;
               scanf( "%d%d%d" , &s , &t , &v ) ;
               g.AddEdge( s , t , v ) ;
        }
        scanf( "%d" , &d ) ;
        while ( d -- ) {
               int p , a , b;
               scanf( "%d%d%d" , &p , &a , &b ) ;
               for ( int i = a ; i <= b ; i ++ ) g.va[ p ][ i ] = false ;
        }
        for ( int i = 0 ; i ++ < n ; ) {
               dp[ i ] = g.cost( 1 , i  ) * i ;
               for ( int j = 0 ; j ++ < i - 1 ; ) dp[ i ] = min( dp[ i ] , dp[ j ] + g.cost( j + 1 , i )*( i - j ) + k ) ;
        }
        printf( "%d\n" , dp[ n ] ) ;
        return 0 ;
}

相关文章

网友评论

    本文标题:BZOJ-1003: [ZJOI2006]物流运输trans(D

    本文链接:https://www.haomeiwen.com/subject/kakkzftx.html