zoukankan      html  css  js  c++  java
  • SGU---103 最短路变形

    题目链接:

    https://cn.vjudge.net/problem/SGU-103#author=ECUST_FZL

    题目大意:

    Dingiville 城市的交通规则非常奇怪,城市公路通过路口相连,两个不同路口之间最多只有一条直达公路。公路的起止点不会是同一路口。在任意一条公路上顺不同方向走所需 时间相同。每一个路口都有交通灯,这些交通灯在某一时刻要么是蓝色,要么是紫色。同一个灯上2个颜色的维持时间受到定期调控,总是蓝色持续一段时间,紫色 持续一段时间。交通规则规定两个路口可以通车仅当公路两边交通灯的颜色相同(也就是说只要你在A城市看见A与B的交通灯颜色相同,那么你就可以走上A-B 这条路并到达B点)。交通工具可以在路口等候。现在你有这个城市的地图,包含:

    • 通过所有公路需要的时间(整数)

    • 每个路口交通灯两种颜色的持续时间(整数)

    • 每个路口交通灯的初始颜色以及初始颜色的持续时间(整数).

    你的任务是找到一条从起点到终点的最快路径,当有多条这样的路径存在时,你只需输出任意一条即可。

    解题思路:

    可以用SPFA求解最短路,只是松弛的时候,计算两点的路径的时候需要计算一下。

    只有u点的颜色和v点的颜色是一致的时候才可以从u到v,可以写出一个函数计算某时刻某个点的颜色,对于u v路径,可以枚举在dis[u] - dis[u] + 300内的所有时间直到两点颜色相同。这是由于周期最多为200,在一个半周期内没有解的话就无解了。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int INF = 0x3f3f3f3f;
      4 const int maxn = 310;
      5 struct Edge
      6 {
      7     int u, v, w;
      8     Edge(){}
      9     Edge(int u, int v, int w):u(u), v(v), w(w){}
     10 };
     11 vector<Edge>edges;//存每一条边
     12 vector<int>Map[maxn];//存i相连的边的下标
     13 void addedge(int u, int v, int w)
     14 {
     15     edges.push_back(Edge(u, v, w));
     16     int m = edges.size();
     17     Map[u].push_back(m - 1);
     18     edges.push_back(Edge(v, u, w));
     19     m = edges.size();
     20     Map[v].push_back(m - 1);
     21 }
     22 
     23 struct node
     24 {
     25     bool color;//color = 0为blue  color = 1为purple
     26     int init, tb, tp, tsum;
     27 }a[maxn];
     28 
     29 int color(int u, int time)//计算time时候 u点的颜色
     30 {
     31     time = (time - a[u].init + a[u].tsum) % a[u].tsum;
     32     if(a[u].color)return time < a[u].tb ? 0 : 1;//最初为紫色的时候
     33     else return time < a[u].tp ? 1 : 0;//最初为蓝色的时候
     34 }
     35 int Time(int u, int v, int now)//返回从u到v可以开始走的时间
     36 {
     37     for(int i = now; i <= now + 300; i++)
     38         if(color(u, i) == color(v, i))return i;
     39     return INF;
     40 }
     41 
     42 bool vis[maxn];
     43 int d[maxn], path[maxn];
     44 int n, m;
     45 int SPFA(int s, int t)
     46 {
     47     memset(vis, 0, sizeof(vis));
     48     memset(path, -1, sizeof(path));
     49     for(int i = 1; i <= n; i++)d[i] = INF;
     50     d[s] = 0;
     51     vis[s] = 1;
     52     queue<int>q;
     53     q.push(s);
     54     while(!q.empty())
     55     {
     56         int u = q.front();
     57         q.pop();
     58         vis[u] = 0;
     59         for(int i = 0; i < Map[u].size(); i++)
     60         {
     61             Edge& e = edges[Map[u][i]];
     62             int v = e.v;
     63             int w = Time(u, v, d[u]) + e.w;//这是u到v的时间
     64             if(d[v] > w)
     65             {
     66                 d[v] = w;
     67                 path[v] = Map[u][i];
     68                 if(!vis[v])
     69                 {
     70                     q.push(v);
     71                     vis[v] = 1;
     72                 }
     73             }
     74 
     75         }
     76     }
     77     return d[t];
     78 }
     79 void Print(int s, int t)
     80 {
     81     stack<int>q;
     82     int x = t;
     83     while(path[x] != -1)
     84     {
     85         q.push(x);
     86         x = edges[path[x]].u;
     87     }
     88     printf("%d", s);
     89     while(!q.empty())
     90     {
     91         printf(" %d", q.top());
     92         q.pop();
     93     }
     94     puts("");
     95 }
     96 int main()
     97 {
     98     int s, t;
     99     char c[5];
    100     scanf("%d%d", &s, &t);
    101     scanf("%d%d", &n, &m);
    102     for(int i = 1; i <= n; i++)
    103     {
    104         scanf("%s%d%d%d", c, &a[i].init, &a[i].tb, &a[i].tp);
    105         a[i].tsum = a[i].tb + a[i].tp;
    106         a[i].color = c[0] == 'P';
    107     }
    108     int u, v, w;
    109     while(m--)
    110     {
    111         scanf("%d%d%d", &u, &v, &w);
    112         addedge(u, v, w);
    113     }
    114     int ans = SPFA(s, t);
    115     if(ans >= INF)
    116     {
    117         printf("0
    ");
    118     }
    119     else
    120     {
    121         printf("%d
    ", ans);
    122         Print(s, t);
    123     }
    124     return 0;
    125 }
  • 相关阅读:
    SQL Server数据库文件存储目录转移
    窗口管理器 dwm安装
    arch linux 安装
    如何在windows 2003(虚拟主机)上面部署MVC3
    .NET接入微信支付(一)JS API接入 V3
    MongoDB部署实战(一)MongoDB在windows平台分片集群部署
    .NET接入UnionPay银联支付(一)手机wap支付
    cas4.2.7 集群服务搭建
    JAVA计算整数的位数
    JAVA求解质因数
  • 原文地址:https://www.cnblogs.com/fzl194/p/9126902.html
Copyright © 2011-2022 走看看