USACO 3.2 Sweet Butter

USACO 3.2 Sweet Butter


稀疏图的多源最短路径问题,用heap+disjktra解决。

#include  < iostream >
#include 
< fstream >
#include 
< list >
#include 
< queue >

using   namespace  std;

ifstream fin(
" butter.in " );
ofstream fout(
" butter.out " );

#ifdef _DEBUG
#define  out cout
#define  in cin
#else
#define  out fout
#define  in fin
#endif

int  n,p,c;

struct  edge{
    
int  node;
    
int  weight;
    edge(
int  n, int  w):node(n),weight(w){
    }
};

struct  graph_node{
   list
< edge >  adj; 
};

struct  pri_que_node{
    
int  num;
    
int  dist;
    pri_que_node(
int  n, int  d):num(n),dist(d){
    };
    
bool   operator <  ( const  pri_que_node  & n2)  const {
        
return  dist > n2.dist;
    }
};

graph_node graph[
801 ];
int  cow_place[ 801 ];
int  shortest_path[ 801 ][ 801 ];

void  get_shortest( int  n)
{
    
for ( int  i = 1 ;i < 801 ; ++ i)
        shortest_path[n][i] 
=  INT_MAX;

    shortest_path[n][n]  =   0 ;
    priority_queue
< pri_que_node >  pq;
    
for (list < edge > ::iterator li  =  graph[n].adj.begin();
                   li
!= graph[n].adj.end();
                   li
++ ){
        pq.push( pri_que_node(li
-> node,li -> weight) );
        shortest_path[n][li
-> node]  =  li -> weight;
    }

    
while ! pq.empty() ){
       pri_que_node node 
=  pq.top();
       pq.pop();

       
if ( node.dist >  shortest_path[n][node.num] )
           
continue ;

       shortest_path[n][node.num] 
=  node.dist;

       
for (list < edge > ::iterator li  =  graph[node.num].adj.begin();
                   li
!= graph[node.num].adj.end();
                   li
++ ){
           
if ( node.dist + li -> weight  <  shortest_path[n][li -> node] ){
               shortest_path[n][li
-> node]  =  node.dist + li -> weight;
               pq.push( pri_que_node(li
-> node, shortest_path[n][li -> node]) );
           }
        }
    }
}

void  solve()
{
    
in >> n >> p >> c;

    
for ( int  i = 0 ;i < n; ++ i)
        
in >> cow_place[i];

    
int  a,b,w;
    
while (c -- ){
        
in >> a >> b >> w;
        graph[a].adj.push_back( edge(b,w) );
        graph[b].adj.push_back( edge(a,w) );
    }
#ifdef _DEBUG
    
for ( int  i = 1 ;i <= p; ++ i){
        
if ( ! graph[i].adj.empty()){
            cout
<< " node: " << i << "   " ;
           
for (list < edge > ::iterator li  =  graph[i].adj.begin();
                   li
!= graph[i].adj.end();
                   li
++ ){
               cout
<< " ( " << li -> node << " , " << li -> weight << " ) " ;
           }
           cout
<< endl;
        }
    }
#endif

    
for ( int  i = 1 ;i <= p; ++ i)
        get_shortest(i);

    
int  res  =  INT_MAX;

    
for ( int  i = 1 ;i <= p; ++ i){
        
int  t  =   0 ;
        
for ( int  j = 0 ;j < n; ++ j){
            t
+=  shortest_path[i][cow_place[j]];
        }
        res 
=  min(res,t);
    }

    
out << res << endl;

}

int  main( int  argc, char   * argv[])
{
    solve(); 
    
return   0 ;
}



你可能感兴趣的:(USACO 3.2 Sweet Butter)