sgu 103 Traffic Lights

10 篇文章 0 订阅
0 篇文章 0 订阅

题目描述:

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:N,M. The following N lines contain information on N junctions. The (i+2)'th line of the input file holds information about the junctioni :Ci, riC, tiB,tiP where Ci is eitherB forblue or P for purple, indicating the initial color of the light at the junctioni. Finally, the nextM lines contain information on M roads. Each line is of the form:i,j, lij 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 throughN. These numbers are called id-numbers. 1 ≤M ≤ 14000 where M is the number of roads. 1 ≤ lij ≤ 100 wherelij is the time required to move from junction i toj using the road that connectsi and j. 1 ≤ tiC ≤ 100 wheretiC is the duration of the colorc for the light at the junctioni. The index c is either 'B' for blue or 'P' for purple. 1 ≤riCtiC where riC is the remaining time for the initial colorc at junctioni.

    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
    


这道题WA了无数次a......,后来才发现是将<=写成==了。。(RP啊)

验证了我的百折不挠。

好了,下面是思路:

是属于路联通性会变化的最短路,我们需要判断t时刻要从u到v我们需要等待的时间。

考虑到我们不会等待超过两个回合,我们可以判断一下,防止TLE(苦逼的TLE。。。)

然后就很好写了。我用的是spfa ,效果还可以。。

附上代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<queue>

#define inf 0xfffffff
#define CLR(a,b) memset((a),(b),sizeof((a)))

using namespace std;
int const nMax = 310;
typedef int LL;
typedef pair<LL,LL> pij;

int dist[nMax],tt[nMax];
int c[nMax],r[nMax],t[nMax][2];  //0->blue 1->purple
vector<pij> Q[nMax];
int n,m;
int so,si;
char s[nMax];
int vis[nMax];
queue<int> q;
int fa[nMax];

int inline f(int u,int T){
    T%=(t[u][0]+t[u][1]);
    if((T<r[u])||(T>=r[u]+t[u][c[u]^1]))return c[u];
    return c[u]^1;
}

int inline next_t(int u,int T){
    int _t=T%(t[u][0]+t[u][1]);
    if((_t<r[u]))return T+r[u]-_t;
    else if(_t>=r[u]&&_t<r[u]+t[u][c[u]^1])return T+r[u]+t[u][c[u]^1]-_t;
    else return T+r[u]+t[u][0]+t[u][1]-_t;
}

int inline next(int u,int v,int T){
    int cu=f(u,T),cv=f(v,T);
    int tu=T;
    int step=0;
    while(cu!=cv){
        tu=min(next_t(u,tu),next_t(v,tu));
        cu=f(u,tu),cv=f(v,tu);
        step++;
        if(step>3)return -1;
    }
    return tu;
}

void inline output(int u){
    if(fa[u]==-1){
        printf("%d",u);
        return ;
    }
    output(fa[u]);
    printf(" %d",u);
    return ;
}

void spfa()
{
    int u,v,w;
    for(int i=1;i<=n;i++){
        dist[i]=inf;
        vis[i]=0;
        tt[i]=0;
    }
    while(!q.empty())q.pop();
    dist[so]=0;
    q.push(so);
    fa[so]=-1;
    while(!q.empty()){
        u=q.front();q.pop();
        vis[u]=0;
        for(int i=0;i<Q[u].size();i++){
            v=Q[u][i].first,w=Q[u][i].second;
            int add=next(u,v,dist[u]);
            if(add==-1)continue;
            if(dist[v]>w+add){
                fa[v]=u;
                dist[v]=w+add;
                if(!vis[v]){
                    q.push(v);
                    vis[v]=1;
                }
            }
         //   printf("u=%d v=%d add=%d dist[%d]=%d dist[%d]=%d\n",u,v,add,u,dist[u],v,dist[v]);
        }
    }
    if(dist[si]==inf)printf("0\n");
    else {
        printf("%d\n",dist[si]);
        output(si);
    }
}

int main()
{
    int u,v,w;
    scanf("%d%d",&so,&si);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%s %d %d %d",s,&r[i],&t[i][0],&t[i][1]);
        c[i]=s[0]=='B'?0:1;
        Q[i].clear();
    }
    for(int i=0;i<m;i++){
        scanf("%d%d%d",&u,&v,&w);
        Q[u].push_back(pij(v,w));
        Q[v].push_back(pij(u,w));
    }
    spfa();
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值