zoukankan      html  css  js  c++  java
  • SGU 103 Traffic Lights 经典最短路

    -----------------

    103. Traffic Lights

    Time limit per test: 0.5 second(s)
    Memory limit: 4096 kilobytes
    input: standard
    output: standard



    In the city of Dingilville the traffic is arranged in an unusual way. There are junctions and roads connecting the junctions. There is at most one road between any two different junctions. There is no road connecting a junction to itself. Travel time for a road is the same for both directions. At every junction there is a single traffic light that is either blue or purple at any moment. The color of each light alternates periodically: blue for certain duration and then purple for another duration. Traffic is permitted to travel down the road between any two junctions, if and only if the lights at both junctions are the same color at the moment of departing from one junction for the other. If a vehicle arrives at a junction just at the moment the lights switch it must consider the new colors of lights. Vehicles are allowed to wait at the junctions. You are given the city map which shows:
  • the travel times for all roads (integers)
  • the durations of the two colors at each junction (integers)
  • and the initial color of the light and the remaining time (integer) for this color to change at each junction. 

    Your task is to find a path which takes the minimum time from a given source junction to a given destination junction for a vehicle when the traffic starts. In case more than one such path exists you are required to report only one of them.

    Input
    The first line contains two numbers: The id-number of the source junction and the id-number of the destination junction. The second line contains two numbers: NM. The following N lines contain information on N junctions. The (i+2)'th line of the input file holds information about the junction i : CiriCtiBtiP where Ci is either B for blue or P forpurple, indicating the initial color of the light at the junction i. Finally, the next M lines contain information on M roads. Each line is of the form: ijlij where i and j are the id-numbers of the junctions which are connected by this road. 2 ≤ N ≤ 300 where N is the number of junctions. The junctions are identified by integers 1 through N. These numbers are called id-numbers. 1 ≤ M ≤ 14000 where M is the number of roads. 1 ≤ lij ≤ 100 where lij is the time required to move from junction i to j using the road that connects i and j. 1 ≤ tiC ≤ 100 where tiC is the duration of the color c for the light at the junction i. The index c is either 'B' for blue or 'P' for purple. 1 ≤ riC ≤ tiC where riC is the remaining time for the initial color c at junction i

    Output
    If a path exists:
  • The first line will contain the time taken by a minimum-time path from the source junction to the destination junction.
  • Second line will contain the list of junctions that construct the minimum-time path you have found. You have to write the junctions to the output file in the order of travelling. Therefore the first integer in this line must be the id-number of the source junction and the last one the id-number of the destination junction. 

    If a path does not exist:
  • A single line containing only the integer 0. 

    Example(s)
    sample input
    sample output
    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
    


    -----------------

    边权随着时间变化。可以证明dijkstra的贪心策略仍然适用。

    所以只要计算出两点间的等待时间即可。

    -----------------

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <queue>
    using namespace std;
    const int maxn=1111;;
    const int maxm=41111;
    const int INF=0x3f3f3f3f;
    int st,ed;
    int n,m;
    struct Node{
        char c[2];
        int r,tb,tp;
    }a[maxn];
    
    class Dijkstra{
    private:
        struct EdgeNode{
            int to,w,next;
        };
        struct HeapNode{
            int u,d;
            HeapNode(int _u,int _d):u(_u),d(_d){}
            bool operator<(const HeapNode& rhs) const{
                return d>rhs.d;
            }
        };
        EdgeNode edges[maxm];
        int head[maxn],edge;
        int dis[maxn],pre[maxn];
        bool vis[maxn];
        priority_queue<HeapNode>que;
        void color(int time,int x,int &px,char cx[]){
            if (time<a[x].r){
                px=a[x].r-time;
                cx[0]=a[x].c[0];
                return;
            }
            int t=(time-a[x].r)%(a[x].tb+a[x].tp);
            if (a[x].c[0]=='B'&&t<a[x].tp){
                px=a[x].tp-t;
                cx[0]='P';
            }
            else if (a[x].c[0]=='P'&&t<a[x].tb){
                px=a[x].tb-t;
                cx[0]='B';
            }
            else{
                px=a[x].tb+a[x].tp-t;
                if (a[x].c[0]=='B') cx[0]='B';
                else cx[0]='P';
            }
        }
    public:
        int getTime(int time,int x,int y,int num){
            if (num>3) return -1;
            int px,py;
            char cx[2],cy[2];
            color(time,x,px,cx);
            color(time,y,py,cy);
            if (cx[0]==cy[0]) return time;
            if (px==py) return getTime(time+px,x,y,num+1);
            time+=min(px,py);
            return time;
        }
    
        void addedge(int u,int v,int w){
            edges[edge].w=w,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
        }
        void init(){
            memset(head,-1,sizeof(head));
            edge=0;
        }
        int getDis(int i){
            return dis[i];
        }
        int getPre(int i){
            return pre[i];
        }
        void dijkstra(int s){
            while (!que.empty()) que.pop();
            memset(dis,0x3f,sizeof(dis));
            memset(vis,0,sizeof(vis));
            memset(pre,-1,sizeof(pre));
            dis[s]=0;
            que.push(HeapNode(s,0));
            while (!que.empty()){
                HeapNode top=que.top();
                que.pop();
                int u=top.u;
                if (vis[u]) continue;
                vis[u]=true;
                for (int i=head[u];i!=-1;i=edges[i].next){
                    int v=edges[i].to;
                    int w=edges[i].w;
                    int time=getTime(dis[u],u,v,1);
                    if (time==-1) continue;
                    if (dis[v]>time+w){
                        dis[v]=time+w;
                        pre[v]=u;
                        que.push(HeapNode(v,dis[v]));
                    }
                }
            }
        }
        void output(int u){
            if (pre[u]!=-1) output(pre[u]);
            else{
                printf("%d",u);
                return;
            }
            printf(" %d",u);
        }
    }dij;
    
    void init(){
        dij.init();
    }
    
    void input(){
        scanf("%d%d",&st,&ed);
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++){
            scanf("%s%d%d%d",a[i].c,&a[i].r,&a[i].tb,&a[i].tp);
        }
        for (int i=1;i<=m;i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            dij.addedge(u,v,w);
            dij.addedge(v,u,w);
        }
    }
    
    void solve(){
        dij.dijkstra(st);
        if (dij.getDis(ed)==INF) printf("0
    ");
        else{
            printf("%d
    ",dij.getDis(ed));
            dij.output(ed);
            printf("
    ");
        }
    }
    
    int main()
    {
        init();
        input();
        solve();
        return 0;
    }
    
    


    -----------------

    -----------------


查看全文
  • 相关阅读:
    [编写高质量代码:改善java程序的151个建议]建议72 生成字列表后不要再操作原列表
    [编写高质量代码:改善java程序的151个建议]建议71 推荐使用subList处理局部列表
    [编写高质量代码:改善java程序的151个建议]建议70 子列表只是原列表的一个视图
    程序员的简历到底该怎么写?(转)
    SQL数据库数据优化SQL优化总结( 百万级数据库优化方案)
    sqlserver的四种分页方式
    sql server中截取字符串的常用函数(自己经常到用的时候想不起来所以拿到这里)
    SQL之存储过程详细介绍及语法(篇幅比较长慢慢看)
    超经典SQL练习题,做完这些你的SQL就过关了
    SqlServer 数据库引擎优化顾问优化数据库(消耗内存很大)
  • 原文地址:https://www.cnblogs.com/cyendra/p/3681548.html
  • Copyright © 2011-2022 走看看