zoukankan      html  css  js  c++  java
  • UVALive 6485 Electric Car Rally (BFS,PQ)

    https://icpcarchive.ecs.baylor.edu/index.php?

    option=com_onlinejudge&Itemid=8&page=show_problem&problem=4496

    In an attempt to demonstrate the practicality of electric cars, ElecCarCo is sponsoring a cross-country
    road rally. There are n charging stations for the rally where cars may check in and charge their batteries.
    The rally may require multiple days of travel. Each car can travel four hours (240 minutes) between
    charges. A car must be plugged into a charger for two minutes for each minute of travel time. Cars
    start the rally at noon on the first day, fully charged. Cars are permitted remain at a station even after
    they are fully charged.
    It is only possible to drive directly between select pairs of stations. Variations in trafc conditions,
    road conditions, availability of HOV lanes, etc., result in different travel times along each route de-
    pending upon the time of day at which travel along that route begins. All roads are two-way, and the
    prevailing conditions affect travel in both directions.
    The winner is the first car to reach checkpoint n − 1, starting form checkpoint 0. Other than the
    starting and ending conditions, cars may pass through the stations in any order, and need not visit all
    stations to complete the course.
    Write a program to determine the earliest time, expressed as the total number of minutes elapsed
    since the start of the rally, at which a car could reach the final checkpoint.
    Input
    There will be several test cases in the input. Each test case starts with a line containing n (1 ≤ n ≤ 500),
    the number of stations, and m (1 ≤ m ≤ 1, 000), the number of connecting road segments.
    This is followed by m blocks, each block describing one road segment. A road segment block has
    the following structure:
    Each block begins with a single line containing two integers, a and b (0 ≤ a, b ≤ n − 1, a ̸= b).
    These numbers are the two checkpoints connected by that segment. The connections are undirected: a
    segment permitting travel from station a to station b will also allow travel from station b to station a.
    This is followed by from one to twenty ‘travel lines’ describing travel times. Each of the travel lines
    contains 3 numbers: Start, Stop, (0 ≤ Start < Stop ≤ 1, 439), and T ime (0 < T ime < 1, 000). Start
    and Stop are the time of day (expressed in minutes since midnight) described by this line, and T ime
    is the travel time, in minutes, required to traverse this road segment if travel begins at any time in the
    range [Start..Stop], inclusive. The first travel line in a block will have a start time of 0 (midnight, or
    00:00). The final travel line in a block will have a stop time of 1439 (i.e., 23:59, or 1 less than 24 hours
    times 60 minutes). Adjacent travel lines in the input will be arranged in order, and the start time of
    any line after the first is one higher than the stop time of the preceding line. The travel lines will cover
    all times from 00:00 to 23:59.
    Input will end with a line with two 0s. All test cases will describe a course that can be completed
    by the cars.
    Output
    For each test case, output a single integer representing the smallest number of minutes needed to
    complete the rally. Output no spaces, and do not separate answers with blank lines.
    Sample Input
    4 4
    0 1
    0 1439 100
    0 2
    0 1439 75
    1 3
    0 720 150
    721 824 100
    825 1000 75
    1001 1439 150
    2 3
    0 1439 150
    3 2
    0 1
    0 10 200
    11 1439 300
    1 2
    0 10 200
    11 1439 300
    4 3
    0 1
    0 719 500
    720 1439 240
    1 2
    0 964 500
    965 1439 2
    2 3
    0 971 500
    972 1439 3
    0 0
    Sample Output
    180
    2360
    255


    题意:

    给一张无向图,中午12:00从0点出发(充满电。支持240分钟的路程),在每一个点都能充电,充2分钟的电能跑1分钟,每条路按分钟分为若干个时间段。每一个时间段内通过这条路的时间为ti。问到达n-1号点最少要多少时间。

    分析:

    BFS+优先队列。按时间优先出队。要注意将电量的存储*2(当然有其它方法)。由于假设充电时间为奇数。用int存会丢失0.5。其次是要跑两个周期(两天)。

    判重的话有非常多方法,较普遍的是开两维,位置和剩余电量,我的方法是开一维松弛,将电量化为0(x.time-x.power)。要小心的是时间段并非按题目描写叙述中说的分为1-20个(This is followed by from one to twenty ‘travel lines’ describing travel times.),而是有24个,该死的非法数据,WA了我两天。都成WA掘机了。交了70多发才A,Total submissions才210。整个OJ的智商都被我拉低了。


    /*
     *
     * Author : fcbruce
     *
     * Time : Sun 05 Oct 2014 06:44:35 PM CST
     *
     */
    #include <cstdio>
    #include <iostream>
    #include <sstream>
    #include <cstdlib>
    #include <algorithm>
    #include <ctime>
    #include <cctype>
    #include <cmath>
    #include <string>
    #include <cstring>
    #include <stack>
    #include <queue>
    #include <list>
    #include <vector>
    #include <map>
    #include <set>
    #define sqr(x) ((x)*(x))
    #define LL long long
    #define itn int
    #define INF 0x3f3f3f3f
    #define PI 3.1415926535897932384626
    #define eps 1e-10
    
    #ifdef _WIN32
      #define lld "%I64d"
    #else
      #define lld "%lld"
    #endif
    
    #define maxm 2333
    #define maxn 507
    
    using namespace std;
    
    struct _record
    {
      int start[24],stop[24],time[24];
      int cnt;
    }w[maxm];
    
    int fir[maxn];
    int u[maxm],v[maxm],nex[maxm];
    int e_max=0;
    
    int vis[maxn];
    bool go[24];
    
    inline int ReadInt()
    {
      int flag=0;
      int data=0;
      char ch=getchar();
      while (ch<'0' || ch>'9')
      {
        if (ch=='-') flag=1;
        ch=getchar();
      }
      do
      {
        data=data*10+ch-'0';
        ch=getchar();
      }while (ch>='0' && ch<='9');
      if (flag) data=-data;
      return data;
    }
    
    
    inline void add_edge(int _u,int _v)
    {
      int &e=e_max;
      e++;
      u[e]=_u;v[e]=_v;
      nex[e]=fir[u[e]];fir[u[e]]=e;
      for (int i=0,start,stop=0,time,j=0;stop!=1439;i++)
      {
        start=ReadInt();
        stop=ReadInt();
        time=ReadInt();
        w[e].start[j]=w[e+1].start[j]=start;
        w[e].stop[j]=w[e+1].stop[j]=stop;
        w[e].time[j]=w[e+1].time[j]=time*2;
        w[e].cnt=w[e+1].cnt=++j;
      }
      e++;
      u[e]=_v;v[e]=_u;
      nex[e]=fir[u[e]];fir[u[e]]=e;
    }
    
    struct Heap_node
    {
      int pos,time,power;
      bool operator < (const Heap_node &_)const
      {
        return time>_.time;
      }
    };
    
    priority_queue<Heap_node> q;
    
    int bfs(int s,int t,int start)
    {
      while (!q.empty()) q.pop();
      memset(vis,0x3f,sizeof vis);
      Heap_node iter=(Heap_node){s,start,480};
      q.push(iter);
      
      while (!q.empty())
      {
        Heap_node x=q.top();q.pop();
        if (x.pos==t) return x.time-start;
        vis[x.pos]=min(vis[x.pos],x.time-x.power);
    
        for (int e=fir[x.pos];~e;e=nex[e])
        {
          if (vis[v[e]]<x.time-x.power) continue;
          memset(go,0,sizeof go);
          int begin;
          for (int i=0;i<w[e].cnt;i++)
            if (x.time% 1440>=w[e].start[i] && x.time% 1440<=w[e].stop[i])
            {
              begin=i;
              break;
            }
    
          if (w[e].time[begin]>480) goto too_far;
          if (x.power>=w[e].time[begin])
          {
            go[begin]=true;
            iter=(Heap_node){v[e],x.time+w[e].time[begin]/2,x.power-w[e].time[begin]};
            q.push(iter);
          }
          else
          {
            int charge=w[e].time[begin]-x.power;
            if (x.time % 1440+charge<=w[e].stop[begin])
            {
              go[begin]=true;
              iter=(Heap_node){v[e],x.time+charge+w[e].time[begin]/2,0};
              q.push(iter);
            }
          }
    too_far:
    
          int plus=0;
          for (int j=begin+1;j<w[e].cnt*2+begin+1;j++)
          {
            int i=j%w[e].cnt;
            if (w[e].start[i]==0) plus+=1440;
            if (w[e].time[i]>480) continue;
            if (go[i]) continue;
            int power=x.power;
            int time=w[e].start[i]+plus-x.time% 1440;
            power+=time;
            power=min(480,power);
            if (power>=w[e].time[i])
            {
              go[i]=true;
              iter=(Heap_node){v[e],x.time+time+w[e].time[i]/2,power-w[e].time[i]};
              q.push(iter);
            }
            else
            {
              int charge=w[e].time[i]-power;
              if (w[e].start[i]+charge<=w[e].stop[i])
              {
                go[i]=true;
                iter=(Heap_node){v[e],x.time+time+charge+w[e].time[i]/2,0};
                q.push(iter);
              }
            }
          }
        }
      }
    }
    
    int main()
    {
    #ifdef FCBRUCE
      freopen("/home/fcbruce/code/t","r",stdin);
    #endif // FCBRUCE
    
      int n,m;
    
      while (scanf("%d%d",&n,&m),n||m)
      {
        memset(fir,-1,sizeof fir);
        e_max=0;
    
        for (int i=0,u,v;i<m;i++)
        {
         // scanf("%d%d",&u,&v);
          u=ReadInt();v=ReadInt();
          add_edge(u,v);
        }
    
        printf("%d
    ",bfs(0,n-1,720));
      }
    
      return 0;
    }
    


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    在阿里云服务器上安装MySQL
    mui中调用ajax时报abort错误
    IDEA根据数据库表生成pojo对象
    java.io.IOException: All specified directories have failed to load.
    mysql隔离级别
    java8新特性
    数据库语言分类
    Spring AOP 代码示例
    java NIO学习(二)
    java NIO学习(一)
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4713137.html
Copyright © 2011-2022 走看看