zoukankan      html  css  js  c++  java
  • SGU 103 Traffic Lights

    SGU_103

        与一般的最短路问题不同的是,我们要首先判断什么时候才可以走上某条路,因此我们需要计算从当前这刻起两个灯变成相同颜色的最近的那一时刻,当然也有可能两灯根本不会变成相同的颜色,总体的一个思想就是如果两灯的一个最小公周期内没有出现相同的颜色,那么后面也一定不会出现相同的颜色。

        在计算等待时间的时候,可以依次枚举也可以一次性加到两灯有其一变化的最近的那一刻。在计算最短路的过程中,也可以适当用一些剪枝以减少计算量,比如如果d[u]+t[i]>=d[v],即就算现在立刻可以上路也不能更新d[v],那么自然就不用计算两个灯在什么候会变成相同颜色了,同时如果枚举过程中当前时刻已经超过了d[v]-t[i],那么也可以终止枚举了。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 310
    #define MAXM 30000
    #define INF 0x5f5f5f5f5f5f5f5fll
    int N, M, S, T, e, first[MAXD], next[MAXM], v[MAXM], w[MAXM], icol[MAXD], it[MAXD], t[MAXD][2];
    int q[MAXD], inq[MAXD], p[MAXD];
    long long int d[MAXD];
    int gcd(int a, int b)
    {
    return b == 0 ? a : gcd(b, a % b);
    }
    void add(int a, int b, int c)
    {
    w[e] = c;
    v[e] = b;
    next[e] = first[a];
    first[a] = e;
    e ++;
    }
    void init()
    {
    int i, j, k, a, b, c;
    char st[5];
    scanf("%d%d", &N, &M);
    for(i = 1; i <= N; i ++)
    {
    scanf("%s%d%d%d", st, &a, &b, &c);
    it[i] = a;
    if(st[0] == 'B')
    {
    icol[i] = 0;
    t[i][0] = c, t[i][1] = b;
    }
    else
    {
    icol[i] = 1;
    t[i][0] = b, t[i][1] = c;
    }
    }
    memset(first, -1, sizeof(first));
    e = 0;
    for(i = 0; i < M; i ++)
    {
    scanf("%d%d%d", &a, &b, &c);
    add(a, b, c);
    add(b, a, c);
    }
    }
    long long int nextt(int a, int b, long long int now, long long int limit)
    {
    int sta, stb;
    long long int i, k;
    k = gcd(t[a][0] + t[a][1], t[b][0] + t[b][1]);
    k = (t[a][0] + t[a][1]) / k * (t[b][0] + t[b][1]);
    if(now + k < limit)
    limit = now + k;
    for(i = now; i < limit; i ++)
    {
    if(i < it[a])
    sta = icol[a];
    else
    {
    k = (i - it[a]) % (t[a][0] + t[a][1]);
    if(k < t[a][0])
    sta = (icol[a] ^ 1);
    else
    sta = icol[a];
    }
    if(i < it[b])
    stb = icol[b];
    else
    {
    k = (i - it[b]) % (t[b][0] + t[b][1]);
    if(k < t[b][0])
    stb = (icol[b] ^ 1);
    else
    stb = icol[b];
    }
    if(sta == stb)
    return i;
    }
    return -1;
    }
    void printpath(int cur)
    {
    if(cur == S)
    printf("%d", S);
    else
    {
    printpath(p[cur]);
    printf(" %d", cur);
    }
    }
    void solve()
    {
    int i, j, front, rear, u;
    long long int k;
    memset(d, 0x5f, sizeof(d));
    d[S] = 0;
    memset(inq, 0, sizeof(inq));
    front = rear = 0;
    q[rear ++] = S;
    while(front != rear)
    {
    u = q[front ++];
    if(front > N)
    front = 0;
    inq[u] = 0;
    for(i = first[u]; i != -1; i = next[i])
    if(d[u] + w[i] < d[v[i]])
    {
    k = nextt(u, v[i], d[u], d[v[i]] - w[i]);
    if(k != -1)
    {
    d[v[i]] = k + w[i];
    p[v[i]] = u;
    if(!inq[v[i]])
    {
    q[rear ++] = v[i];
    if(rear > N)
    rear = 0;
    inq[v[i]] = 1;
    }
    }
    }
    }
    if(d[T] == INF)
    printf("0\n");
    else
    {
    printf("%lld\n", d[T]);
    printpath(T);
    printf("\n");
    }
    }
    int main()
    {
    while(scanf("%d%d", &S, &T) == 2)
    {
    init();
    solve();
    }
    return 0;
    }


  • 相关阅读:
    web.xml中<web-app>报错
    groovy初体验:groovy在java中的应用
    Mac安装JMeter时Unable to access jarfile ./ApacheJMeter.jar 解决方法
    intellij idea中解决java.lang.VerifyError: Expecting a stackmap frame at branch target的方法
    关于go get无法安装国内被墙软件解决办法
    Oracle 序列
    无锁并发框架Disruptor学习入门
    vsftp服务器部署
    FinalShell 推荐
    supperset (python 2.7.12 + mysql)记录
  • 原文地址:https://www.cnblogs.com/staginner/p/2282766.html
Copyright © 2011-2022 走看看