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\n"), 0;
    printf("%d\n", dist[tt]);
    output(tt);
    return 0;
}

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com