PKU 1158 Traffic Lights

PKU 1158 Traffic Lights

问题:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1158

思路:
按照Dijkstra算法的思路来求解,关键是每确定一个顶点的更新操作需要考虑因为交通灯导致的等待时间
算法本身并不复杂,自己写出来以后一直TLE...
分析之后的原因是计算两个junctions之间等待交通灯一致所需要等待的时间这一代码块会导致超时
我自己的naive想法是依次递增等待时间(加1),然后检查交通灯是否一致
去图书馆看书的时候突然想到可以取模,但本质还是递增检查,结果还是TLE

参考了别人代码后发现,在取模之后,就可以分情况讨论,直接得出等待时间

参考:
http://blog.sina.com.cn/s/blog_5c95cb070100cxtr.html

代码:
  1  #include < stdio.h >
  2  #include < stdlib.h >
  3  #include < string .h >
  4  #define  MAX_N 301
  5  #define  INF 0x7FFFFFFF
  6  #define  Min(a, b) ((a)<(b) ? (a) : (b))
  7  struct  Junction {
  8       int  color;  /*  0: blue, 1: purple  */
  9       int  left;
 10       int  dur[ 2 ];  /*  0: blue, 1: purple  */
 11  }junctions[MAX_N];
 12  int  from, to;
 13  int  n, m;
 14  int  adj[MAX_N][MAX_N], d[MAX_N],  in [MAX_N];
 15 
 16  void
 17  find_color( int  index,  int  past,  int   * color,  int   * left)  /*  past: the time past from 0  */
 18  {
 19       int  i;
 20       if (past  <  junctions[index].left) {
 21           * color  =  junctions[index].color;
 22           * left  =  junctions[index].left  -  past;
 23           return ;
 24      }
 25      past  -=  junctions[index].left;
 26      past  =  past % (junctions[index].dur[ 0 +  junctions[index].dur[ 1 ]);
 27       if (junctions[index].color  ==   0 ) {
 28           if (past < junctions[index].dur[ 1 ]) {
 29               * color  =   1 ;
 30               * left  =  junctions[index].dur[ 1 -  past;
 31          }  else  {
 32               * color  =   0 ;
 33               * left  =  junctions[index].dur[ 0 +  junctions[index].dur[ 1 -  past;
 34          }
 35      }
 36       else  {
 37           if (past < junctions[index].dur[ 0 ]) {
 38               * color  =   0 ;
 39               * left  =  junctions[index].dur[ 0 -  past;
 40          }  else  {
 41               * color  =   1 ;
 42               * left  =  junctions[index].dur[ 0 +  junctions[index].dur[ 1 -  past;
 43          }
 44      }
 45  }
 46 
 47  void
 48  update( int  index,  int  bt)  /*  bt: the beginning time for current update  */
 49  {
 50       int  i, tm, color_a, color_b, left_a, left_b;
 51       for (i = 1 ; i <= n; i ++ ) {
 52           if ( ! in [i]  &&  adj[index][i]  &&  d[i] > bt + adj[index][i]) {
 53              find_color(index, bt,  & color_a,  & left_a);
 54              find_color(i, bt,  & color_b,  & left_b);
 55               if (color_a  ==  color_b)
 56                  tm  =   0 ;
 57               else  {
 58                   if (left_a  !=  left_b)
 59                      tm  =  Min(left_a, left_b);
 60                   else  {
 61                       if (color_a  ==   0 ) {
 62                           if (junctions[index].dur[ 1 !=  junctions[i].dur[ 0 ])
 63                              tm  =  left_a  +  Min(junctions[index].dur[ 1 ], junctions[i].dur[ 0 ]);
 64                           else   if (junctions[index].dur[ 0 !=  junctions[i].dur[ 1 ])
 65                              tm  =  left_a  +  junctions[index].dur[ 1 +  Min(junctions[index].dur[ 0 ], junctions[i].dur[ 1 ]);
 66                           else
 67                              tm  =  INF;
 68                      }
 69                       else  {
 70                           if (junctions[index].dur[ 0 !=  junctions[i].dur[ 1 ])
 71                              tm  =  left_a  +  Min(junctions[index].dur[ 0 ], junctions[i].dur[ 1 ]);
 72                           else   if (junctions[index].dur[ 1 !=  junctions[i].dur[ 0 ])
 73                              tm  =  left_a  +  junctions[index].dur[ 0 +  Min(junctions[index].dur[ 1 ], junctions[i].dur[ 0 ]);
 74                           else
 75                              tm  =  INF;
 76                      }
 77                  }
 78              }
 79               if (tm != INF  &&  d[i] > d[index] + adj[index][i] + tm)
 80                  d[i]  =  d[index] + adj[index][i] + tm;
 81          }
 82      }
 83  }
 84 
 85  void
 86  dijkstra( int  source)
 87  {
 88       int  i, j, k, cur;
 89      memset( in 0 sizeof ( in ));
 90       for (i = 1 ; i <= n; i ++ )
 91          d[i]  =  INF;
 92       in [source]  =   1 ;
 93      d[source]  =   0 ;
 94      update(source,  0 );
 95       for (i = 2 ; i <= n; i ++ ) {
 96          cur  =  INF;
 97           for (j = 1 ; j <= n; j ++ )
 98               if ( ! in [j]  &&  d[j] <= cur) {
 99                  k  =  j;
100                  cur  =  d[j];
101              }
102           in [k]  =   1 ;
103           if (k  ==  to)
104               break ;
105           if (d[k]  !=  INF)
106              update(k, d[k]);
107      }
108  }
109 
110  void
111  input_init()
112  {
113       int  i, f, t, c;
114       char  tmp[ 2 ];
115      scanf( " %d %d " & n,  & m);
116       for (i = 1 ; i <= n; i ++ ) {
117          scanf( " %s %d %d %d " , tmp,  & junctions[i].left,  & (junctions[i].dur[ 0 ]),  & (junctions[i].dur[ 1 ]));
118          junctions[i].color  =  (tmp[ 0 ] == ' B '   ?   0  :  1 );
119      }
120      memset(adj,  0 sizeof (adj));
121       for (i = 0 ; i < m; i ++ ) {
122          scanf( " %d %d %d " & f,  & t,  & c);
123          adj[f][t]  =  c;
124          adj[t][f]  =  c;
125      }
126  }
127 
128  int
129  main( int  argc,  char   ** argv)
130  {
131       while (scanf( " %d %d " & from,  & to)  !=  EOF) {
132          input_init();
133          dijkstra(from);
134          printf( " %d\n " , d[to] == INF  ?   0  : d[to]);
135      }
136  }

你可能感兴趣的:(PKU 1158 Traffic Lights)