HDOJ 2066 HDU 2066 一个人的旅行 ACM 2066 IN HDU

MiYu原创, 转帖请注明 : 转载自 ______________白白の屋

题目地址:
         http://acm.hdu.edu.cn/showproblem.php?pid=2066
题目描述:
一个人的旅行
Time Limit: 
1000 / 1000  MS (Java / Others)    Memory Limit:  32768 / 32768  K (Java / Others)
Total Submission(s): 
4077     Accepted Submission(s):  1348


Problem Description
虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗
~ ),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子, ^ 0 ^ ),很多事,还能丰富自己的阅历,还可以看美丽的风景……草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽约纯粹看雪景,去巴黎喝咖啡写信,去北京探望孟姜女……眼看寒假就快到了,这么一大段时间,可不能浪费啊,一定要给自己好好的放个假,可是也不能荒废了训练啊,所以草儿决定在要在最短的时间去一个自己想去的地方!因为草儿的家在一个小镇上,没有火车经过,所以她只能去邻近的城市坐火车(好可怜啊 ~ )。
 

Input
输入数据有多组,每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个,草儿想去的地方有D个;
接着有T行,每行有三个整数a,b,time,表示a,b城市之间的车程是time小时;(
1 =< (a,b) <= 1000 ;a,b 之间可能有多条路)
接着的第T
+ 1行有S个数,表示和草儿家相连的城市;
接着的第T
+ 2行有D个数,表示草儿想去地方。
 

Output
输出草儿能去某个喜欢的城市的最短时间。
 

Sample Input
6   2   3
1   3   5
1   4   7
2   8   12
3   8   4
4   9   12
9   10   2
1   2
8   9   10
 

Sample Output
9

题目分析:
        刚开始做的时候也没做分析, 直接就是枚举每个起点到每个终点的 最短距离, 然后取最短的路,  很显然, TLE.................
还是自己没有把DIJKSTRA 算法理解好.... 再次看了一遍算法的描述和数据结构书上的 sample后 发现, 其实算法执行过程中
已经把起点到其他点的最短距离全部算出来了, 所以只需要 枚举每个起点就可以了, 兴奋之下, 马上修改了代码, Submit! ......
很 杯具, 还是tle ...... 不明白为什么.....看网上其他人写的 解题报告 , 原来很多人也是这做的, 枚举起始点, 但是他们的却可以AC.
虽然时间一般是 100MS左右. 这里我一直很纠结, 不明白同样的算法为什么我的会TLE.    
         在 AMB 大牛的提示下, 不需要全部枚举, 只要把所有起点的距离都设置成0就可以了,  但是不知道为什么, 还是一直TLE.

最后的办法是:   设置一个起点指向所有起点, 之间的距离设置为 1, 同样 设置一个终点指向所有终点, 距离同样设置为1, 最后
使用 DIJKSTRA 算法 求出起点到终点的最短距离 - 2 就行了. 

代码如下:
#include  < iostream >
using   namespace  std;
const   int  INF  =   0x7FFFFFFF ;
int  T,S,D,L;
const   int  MAXN = 1005 ;     // 点个数
int  graph[MAXN][MAXN];
int  s[MAXN];
int  d[MAXN];
int  Dijkstra (  int  beg,  int  end )
{
    
bool  hash[MAXN];
    
int  path[MAXN];
    
for  (  int  i  =   0 ; i  <=  L;  ++  i )
    {
          hash[i] 
=   true ;
          path[i] 
=  INF; 
    } 
    hash[beg] 
=   false ;
    path[beg] 
=   0 ;
    
while  ( beg  !=  end )
    {
           
for  (  int  i  =   0 ; i  <=  L;  ++  i )
           {
                 
if  ( graph[beg][i]  !=   0  )
                 {
                      
if  ( path[i]  >  path[beg]  +  graph[beg][i] ) 
                           path[i] 
=  path[beg]  +  graph[beg][i];
                 } 
           } 
           
int  min  =  INF;
           
for  (  int  i  =   0 ; i  <=  L;  ++  i )
           {
                 
if  ( min  >  path[i]  &&  hash[i] )
                 {
                      min 
=  path[i];
                      beg 
=  i; 
                 } 
           }
           hash[beg] 
=   false ;
    }   
    
return  path[end];
}

int  main ()

    
while  ( scanf (  " %d%d%d " , & T, & S, & D )  !=  EOF )
    {
          memset ( graph , 
0  ,  sizeof  ( graph ) );
          L 
=   0 ;
          
for  (  int  i  =   1 ; i  <=  T;  ++  i )
          {
                
int  r,c,cost;
                scanf ( 
" %d%d%d " , & r, & c, & cost );
                
if  ( graph[r][c]  ==   0  )
                     graph[r][c] 
=  graph[c][r]  =  cost ;
                
else
                {
                     
if  ( cost  <  graph[r][c] ) 
                          graph[r][c] 
=  graph[c][r]  =  cost ;
                }
                
if  ( L  <  max ( r,c ) )
                     L 
=  max ( r,c );
          } 
          
for  (  int  i  =   0 ; i  !=  S;  ++  i )
          {
               scanf ( 
" %d " , & s[i] );
               graph[
0 ][ s[i] ]  =   1
               graph[ s[i] ][
0 =   1 ;     
          }
          L 
++ ;
          
for  (  int  i  =   0 ; i  !=  D;  ++  i )
          {
               scanf ( 
" %d " , & d[i] );
               graph[ d[i] ][ L ] 
=   1 ;
               graph[ L ][ d[i] ] 
=   1 ;
          }
          
          cout 
<<  Dijkstra (  0 ,L )  -   2   <<  endl;  
    }
    
return   0



顺便 0rz 下大牛 代码:
#include  < iostream >
#define  MAX 1005
#define  INF 0x7FFF
#define  CMP(A,B) (A.d < B.d)
using   namespace  std;
int  d[MAX][MAX];
class  HNode {
      
public :
              
int  v;
              
int  d;
};
class  Heap {
public :
        HNode h[MAX 
*   2 ];
        
int  n, p, c;
        Heap() {
                n 
=   0 ;
        }
        
void  inline ins(HNode e) {
                
for  (p  =   ++ n; p  >   1   &&  CMP(e,h[p >> 1 ]); h[p]  =  h[p >> 1 ], p  >>=   1 )
                        ;
                h[p] 
=  e;
        }
        
int  inline pop(HNode  & e) {
                
if  ( ! n)
                        
return   0 ;
                
for  (e  =  h[p  =   1 ], c  =   2 ; c  <  n
                                
&&  CMP(h[c  +=  (CMP(h[c  +   1 ],h[c])  &&  c  <  n  -   1 )], h[n]);
                                h[p] 
=  h[c], p  =  c, c  <<=   1 )
                        ;
                h[p] 
=  h[n -- ];
                
return   1 ;
        }
};
int  Dijkstra( int  A,  int  B,  int  N) {
        
int  dist[MAX];
        
int  mask[MAX];
        
int  Tmp;
        Heap h;
        HNode e, ne;

        
for  ( int  i  =   0 ; i  <  N; i ++ ) {
                dist[i] 
=  INF;
                mask[i] 
=   0 ;
        }
        dist[e.v 
=  A]  =  (e.d  =   0 );
        h.ins(e);
        
while  (h.pop(e)) {
                
if  ( ! mask[e.v]) {
                        mask[e.v] 
=   1 ;
                        
for  ( int  i  =   0 ; i  <  N; i ++ ) {
                                
if  ( ! mask[i]  &&  (Tmp  =  e.d  +  d[e.v][i])
                                                
<  dist[i]) {
                                        dist[ne.v 
=  i]  =  (ne.d  =  Tmp);
                                        h.ins(ne);
                                }
                        }
                }
        }
        
return  dist[B];
}
int  main() {
        
int  T, S, D, M;
        
int  st, en, tm;
        
while  (scanf( " %d %d %d " & T,  & S,  & D) != EOF) {
                M 
=   0 ;
                
for  ( int  i  =   0 ; i  <  MAX; i ++ )
                        
for  ( int  j  =   0 ; j  <  MAX; j ++ )
                                d[i][j] 
=  INF;
                
for  ( int  i  =   0 ; i  <  T; i ++ ) {
                        scanf(
" %d %d %d " & st,  & en,  & tm);
                        
if  (tm  <  d[st][en]) {
                                d[st][en] 
=  d[en][st]  =  tm;
                        }

                        M 
=  st >  M  ?  st : M;
                        M 
=  en >  M  ?  en : M;
                }
                M 
=  M  +   1 ;
                
for  ( int  i  =   0 ; i  <  S; i ++ ) {
                        scanf(
" %d " & st);
                        d[
0 ][st]  =   1 ;
                        d[st][
0 =   1 ;
                }

                
for  ( int  i  =   0 ; i  <  D; i ++ ) {
                        scanf(
" %d " & en);
                        d[M][en] 
=   1 ;
                        d[en][M] 
=   1 ;
                }
                cout
<< Dijkstra( 0 , M, M + 1 ) - 2 << endl;
        }
        
return   0 ;
}

转载于:https://www.cnblogs.com/MiYu/archive/2010/08/18/1802745.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值