• 解题报告 Lights


    Lights

    【题目描述】

    Spray来到了zz城。这个城市的的交通规则非常奇怪,城市公路通过路口相连,两个不同路口之间最多只有一条直达公路。公路的起止点不会是同一路口。在任意一条公路上顺不同方向走所需时间相同。每一个路口都有交通灯,这些交通灯在某一时刻要么是蓝色,要么是紫色。同一个灯上2个颜色的维持时间受到定期调控,总是蓝色持续一段时间,紫色持续一段时间。交通规则规定两个路口可以通车仅当公路两边交通灯的颜色相同(也就是说只要你在A路口看见A与B的交通灯颜色相同,那么就可以走上A-B这条路并到达B路口)。交通工具可以在路口等候。

    现在Spray有这个城市的地图,包含:

    ·1.  通过所有公路需要的时间(整数)

    ·2.  每个路口交通灯两种颜色的持续时间(整数)

    ·3.  每个路口交通灯的初始颜色以及初始颜色的持续时间(整数). 

        你的任务是帮Spray找到一条从起点到终点的最快路径(保证路径唯一)。【输入数据】

    第一行包含两个整数: 起点和终点的编号. 

    第二行包含两个整数: N, M. (2 ≤ N ≤ 300 ,1 ≤ M ≤ 14000)

    接下来 N 行描述 N 个路口的情况. 

    第i+2行 是 i 号路口的信息: Ci, riC, tiB, tiP 。

    其中字符 Ci 要么是“B”代表蓝色,要么是“P”代表紫色,表示 i 的起始颜色. riC, tiB, tiP 分别表示初始颜色,蓝色,紫色的持续时间, 

    (1 ≤ tiC ≤ 100 . 1 ≤ riC ≤ tiC )

    最后的 M 行表示关于 M 条公路的信息。包含: i, j, lij 。i 和 j 号路口被这条路连接. lij 是通过i到j这条公路需要的时间。(1 ≤ lij ≤ 100)

    【输出数据】

    如果存在最短路径:

    第一行输出最短时间。

    第二行是一个对应第一行答案的路口编号表,从起点到终点输出路口编号,数字之间用空格隔开(即输出路径方案)。
    如果不存在,直接输出“0”。

    【样例输入】

    1 4
    4 5
    B 2 16 99
    P 6 32 13
    P 2 87 4
    P 38 96 49
    1 2 4
    1 3 40
    2 3 75
    2 4 76
    3 4 77

    【样例输出】

    127
    1 2 4

     

     

     

    四维 SPFA 

    好理解,不好打。

     

    注意 ci 是初始颜色还需要维持的时间。

     

     

     

    program lonely;

      const

        maxn=10000;

        man=1000000000;

      type

        rec=record

          t:array[0..1] of longint;

          st,tst:longint;

        end;

        nod=record

          y,len,next:longint;

        end;

      var

        a:array[0..400] of rec;

        map:array[0..30000] of nod;

        first:array[0..400] of longint;

        f,dist:array[0..400] of longint;

        v:array[0..400] of boolean;

        tot,extra,st,en,head,tail,x,y,len,t,i,n,m:longint;

        c:char;

        que:array[0..10000] of longint;

      function min(a,b:longint):longint;

        begin

          if a<b then exit(a) else exit(b);

        end;

      function can(x,y,time:longint):boolean;

        var

          ta,tb,tta,ttb:longint;

        begin

          if (time<a[x].tst)and(time<a[y].tst) then

            begin

              if a[x].st=a[y].st then exit(true);

              ta:=a[x].tst-time;

              tb:=a[y].tst-time;

              if ta=tb then

                begin

                  if a[x].t[1-a[x].st]=a[y].t[1-a[y].st] then

                    begin

                      if a[x].t[a[x].st]=a[y].t[a[y].st] then

                        extra:=1000000000

                      else extra:=min(a[x].t[a[x].st],a[y].t[a[y].st])+ta+a[x].t[1-a[x].st];

                    end

                  else extra:=min(a[x].t[1-a[x].st],a[y].t[1-a[y].st])+ta;

                end

              else extra:=min(ta,tb);

              exit(false);

            end;

          if (time>=a[x].tst)and(time<a[y].tst) then

            begin

              ta:=(time-a[x].tst) mod (a[x].t[1]+a[x].t[0]);

              if (ta>a[x].t[1-a[x].st]) then

                begin

                  if a[x].st=a[y].st then exit(true)

                    else

                      begin

                        ta:=a[x].t[1]+a[x].t[0]-ta;

                        tb:=a[y].tst-time;

                        if ta=tb then

                          begin

                            if a[x].t[1-a[x].st]=a[y].t[1-a[y].st] then

                              begin

                                if a[x].t[a[x].st]=a[y].t[a[y].st] then

                                  extra:=1000000000

                                else extra:=min(a[x].t[a[x].st],a[y].t[a[y].st])+ta+a[x].t[1-a[x].st];

                              end

                            else extra:=min(a[x].t[1-a[x].st],a[y].t[1-a[y].st])+ta;

                          end

                        else extra:=min(ta,tb);

                        exit(false);

                      end;

                end

              else

                begin

                  if 1-a[x].st=a[y].st then exit(true)

                    else

                      begin

                        ta:=a[x].t[1-a[x].st]-ta;

                        tb:=a[y].tst-time;

                        if ta=tb then

                          begin

                            if a[x].t[a[x].st]=a[y].t[1-a[y].st] then

                              begin

                                if a[x].t[1-a[x].st]=a[y].t[a[y].st] then

                                  extra:=1000000000

                                else extra:=min(a[x].t[1-a[x].st],a[y].t[a[y].st])+ta+a[x].t[a[x].st];

                              end

                            else extra:=min(a[x].t[a[x].st],a[y].t[1-a[y].st])+ta;

                          end

                        else extra:=min(ta,tb);

                        exit(false);

                      end;

                end;

            end;

          if (time>=a[x].tst)and(time>=a[y].tst) then

            begin

              ta:=(time-a[x].tst) mod (a[x].t[1]+a[x].t[0]);

              tb:=(time-a[y].tst) mod (a[y].t[1]+a[y].t[0]);

              if (ta>a[x].t[1-a[x].st]) then

                begin

                  ta:=a[x].t[1]+a[x].t[0]-ta;

                  tta:=a[x].st

                end

              else

                begin

                  tta:=1-a[x].st;

                  ta:=a[x].t[tta]-ta;

                end;

              if (tb>a[y].t[1-a[y].st]) then

                begin

                  tb:=a[y].t[1]+a[y].t[0]-tb;

                  ttb:=a[y].st

                end

              else

                begin

                  ttb:=1-a[y].st;

                  tb:=a[y].t[ttb]-tb;

                end;

              if tta=ttb then exit(true)

                else

                  begin

                    if ta=tb then

                      begin

                        if a[x].t[1-tta]=a[y].t[1-ttb] then

                          begin

                            if a[x].t[tta]=a[y].t[ttb] then

                              extra:=1000000000

                            else extra:=min(a[x].t[tta],a[y].t[ttb])+ta+a[x].t[1-tta];

                          end

                        else extra:=min(a[x].t[1-tta],a[y].t[1-ttb])+ta;

                      end

                    else extra:=min(ta,tb);

                    exit(false);

                  end;

            end;

          exit(false);

        end;

      procedure print(x:longint);

        begin

          if x=0 then exit;

          print(f[x]);

          write(x,' ');

        end;

      begin

        assign(input,'lights.in');

        reset(input);

        assign(output,'lights.out');

        rewrite(output);

        readln(st,en);

        readln(n,m);

        fillchar(a,sizeof(a),255);

        for i:=1 to n do

          begin

            read(c);

            if c='P' then a[i].st:=0 else a[i].st:=1;

            read(c);

            readln(a[i].tst,a[i].t[1],a[i].t[0]);

          end;

        tot:=0;

        for i:=1 to m do

          begin

            readln(x,y,len);

            inc(tot);

            map[tot].y:=y;map[tot].len:=len;

            map[tot].next:=first[x];

            first[x]:=tot;

            inc(tot);

            map[tot].y:=x;map[tot].len:=len;

            map[tot].next:=first[y];

            first[y]:=tot;

          end;

        for i:=1 to n do dist[i]:=man;

        dist[st]:=0;

        f[st]:=0;

        v[st]:=true;

        head:=0;tail:=1;

        que[tail]:=st;

        while head<>tail do

          begin

            inc(head);

            if head>maxn then head:=1;

            x:=que[head];

            t:=first[x];

            while t<>0 do

              begin

                y:=map[t].y;

                extra:=0;

                if (can(x,y,dist[x]))or(can(y,x,dist[x])) then

                  begin

                    if dist[x]+map[t].len<dist[y] then

                      begin

                        dist[y]:=dist[x]+map[t].len;

                        f[y]:=x;

                        if not v[y] then

                          begin

                            v[y]:=true;

                            inc(tail);

                            if tail>maxn then tail:=1;

                            que[tail]:=y;

                          end;

                      end;

                  end

                else if dist[x]+map[t].len+extra<dist[y] then

                  begin

                    dist[y]:=dist[x]+map[t].len+extra;

                    f[y]:=x;

                    if not v[y] then

                      begin

                        v[y]:=true;

                        inc(tail);

                        if tail>maxn then tail:=1;

                        que[tail]:=y;

                      end;

                  end;

                t:=map[t].next;

              end;

            v[x]:=false;

          end;

        if dist[en]<man then

          begin

            writeln(dist[en]);

            print(f[en]);

            writeln(en);

          end

        else writeln(0);

        close(input);

        close(output);

      end.

  • 相关阅读:
    java8 parallel并行处理实战
    java相关技术问答(二)
    [安卓基础] 007.管理Activity的生命周期
    [Python基础]009.os模块(1)
    [Objective-C] 012_数据持久化_XML属性列表,NSUserDefaults
    SD.Team团队人物形象
    读Pyqt4教程,带你入门Pyqt4 _013
    [Objective-C] 011_数据持久化_NSKeyedArchiver
    [Objective-C] 010_Foundation框架之NSSet与NSMutableSet
    [JavaWeb基础] 007.Struts2的配置和简单使用
  • 原文地址:https://www.cnblogs.com/SueMiller/p/2226670.html
Copyright © 2020-2023  润新知