• SGU 103 Traffic Lights【最短路】


    题目链接:

    http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=16530

    题意:

    给定每个点最初的颜色,最初颜色持续时间,以及每个颜色的持续时间。每个点的颜色蓝紫交替,只有等待到一条路的两个端点颜色相同才能通行。到达某点时颜色恰好变色,则按照变色之后的颜色考虑。
    给定道路的花费,问最少需要多少时间。

    分析:

    最短路问题。
    dijk可做,麻烦之处在于要加上等待时间。对于每个点,判断相邻点颜色是否一致,不一致则选取当前颜色持续时间较短的一个作为等待时间。颜色相同的循环周期最多3次,3次之后颜色仍然无法一致则该路不通。
    注意点数很少,边数很多,肯定有重边存在,选择邻接矩阵的形式。

    代码:

    #include<iostream>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define sa(a) scanf("%d", &a)
    #define fi first
    #define se second
    #define MEM(a, b) memset(a, b, sizeof(a));
    typedef pair<int, int >p;
    const int maxn = 300 + 5, INF = 0x3f3f3f3f;
    struct junction{int color; int r; int t[2];};
    junction j[maxn];
    int pa[maxn];
    int dist[maxn];
    int ss, tt;
    int mm[maxn][maxn];
    int getcolor(int time, int u)
    {
        if(time < j[u].r) return j[u].color;
        int res = (time - j[u].r) % (j[u].t[0] + j[u].t[1]);
        if(res < j[u].t[1 - j[u].color]) return 1 - j[u].color;
        return j[u].color;
    }
    int hold(int u, int v, int time)
    {
        int ans = 0;
        int cnt = 0;
        int res1, res2, res;
        while(cnt < 3){
            int cc = getcolor(time, u);
            int ccc = getcolor(time, v); 
            if(cc == ccc) return ans;
            if(time< j[v].r) res1 = j[v].r - time;
            else{
                res = (time - j[v].r) % (j[v].t[0] + j[v].t[1]);
                if(ccc == j[v].color) res1 = j[v].t[0] + j[v].t[1] - res;
                else res1 = j[v].t[ccc] - res;
            }
            if(time < j[u].r) res2 = j[u].r - time;
            else{
                res = (time - j[u].r) % (j[u].t[0] + j[u].t[1]);
                if(cc == j[u].color) res2 = j[u].t[0] + j[u].t[1] - res;
                else res2 = j[u].t[cc] - res;
            }
            ans += min(res1, res2);
            time += min(res1, res2);
            cnt++;
        }
        return -1;
    }
    void dijkstra(int n)
    {
        priority_queue<p>q;
        q.push(p(0,ss));
        dist[ss] = 0;
        while(!q.empty()){
            p t = q.top();q.pop();
            int u = t.se;
            if(t.fi > dist[u]) continue;
            for(int i = 1; i <= n;i++){
                if(mm[u][i] == INF) continue;
                int tmp =  hold(i, u, dist[u]);
                if(tmp == -1) continue;
                if(mm[i][u] + tmp + dist[u] < dist[i]){
                    pa[i]=u;
                    dist[i] = mm[i][u] + tmp + dist[u];
                    q.push(p(dist[i], i));
                }
            }
        }
    }
    void init()
    {
        MEM(pa, -1);
        MEM(dist, 0x3f);
        MEM(mm, 0x3f);
    }
    void output(int t)
    {
        if(t == -1) return;
        output(pa[t]);
        printf("%d ", t);
    }
    int main (void)
    {
       sa(ss),sa(tt);
       init();
       int n, m; sa(n),sa(m);
       char c;
       int a, b, d, t;
       getchar();
       for(int i = 1; i <= n; i++){
          if(getchar() == 'B') t = 0;
          else t = 1;
          scanf("%d%d%d", &a, &b, &d);
          j[i].color = t;
          j[i].r = a;
          j[i].t[0] = b;
          j[i].t[1] = d;
          getchar();
        }
       for(int i = 0; i < m; i++){
          scanf("%d%d%d", &a, &b, &d);
          mm[a][b] = mm[b][a] = d;
       }
        dijkstra(n);
        if(dist[tt] == INF) return printf("0
    "), 0;
        printf("%d
    ", dist[tt]);
        output(tt);
        return 0;
    }
    
  • 相关阅读:
    Visual Basic 9.0 前沿播报·静态篇(二)对象初始化器和匿名类型
    Visual Basic 9.0 前沿播报内容概览
    Refactor! for VB —— VB2005的重构支持(一)
    我不知道该说什么,这里太先进了!
    Visual Basic 9.0 前沿播报·静态篇(一)局部变量类型推测和数组初始化器
    关于“就地颠倒句子里的词”面试题
    Visual Basic 9.0 前沿播报·静态篇(三)扩展方法
    《窝窝世界》视频20101025
    Silverlight 游戏开发小技巧:透明背景的Silverlight程序
    Silverlight 游戏开发小技巧:技能冷却效果2(Cooldown)2
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758653.html
Copyright © 2020-2023  润新知