蓝桥杯第十三届蓝桥杯大赛软件赛决赛CC++ 研究生组之交通信号

蓝桥杯第十三届蓝桥杯大赛软件赛决赛C/C++ 研究生组之交通信号

题目链接[0交通信号 - 蓝桥云课 (lanqiao.cn)]

本题的思路十分简单,先看题意,是由n个节点,m条边的有向图,红绿灯的顺序为绿黄红黄,在最开始时候为绿灯,绿灯时可以通过这条边,黄灯时不可以走,红灯时则可以反方向走。每次往哪儿走,就在于到达这个边的一瞬间,看此时亮的是什么颜色的灯。

使用小顶堆来存储花费的时间,每次花费最少的时间是在最上面,在对图初始化时候,分为正方向可以走的,以及反向走的,由于该图是个有向图,因而要进行这样的初始化。然后就可以模拟这个过程来取得最短的时间,可以参考一下代码来进行理解。

代码如下:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 10;
struct edge{
  int v;
  int g;
  int r;
  int y;
};
struct dis{
  ll d;
  int u;
  bool operator < (dis d1) const{return d1.d<d;} //自定义比较函数
};
int n, m, s, t;
vector<edge> zheng[N], fan[N];
int main()
{
  priority_queue<dis> q;  //小顶堆
  cin>>n>>m>>s>>t;
  for(int i = 1; i <= m; i++)
  {
    int u,v,g,r,d;
    scanf("%d%d%d%d%d", &u, &v, &g, &r, &d);
    zheng[u].push_back({v,g,r,d});
    fan[v].push_back({u, g, r, d});
  }
  q.push({0, s});
  vector<ll> f(n+1, LONG_MAX);//初始化时间为最长
  f[s]=0;//起始顶点设置为0
  while(q.size())
  {
      auto[times,node] = q.top();
      q.pop();
      for(auto &e:zheng[node]) //需要绿灯的时候才可以走
      {
          ll temp=f[node]%(1ll*e.g+e.y+1ll*e.r+e.y); //*1.ll是为了让其保持long long的数据范围
          if(temp<e.g) //此时正处于绿灯
          {
              if(f[e.v]>f[node]+e.y)
              {
                  f[e.v] = f[node]+e.y; //将该节点的值修改
                  q.push({f[e.v],e.v});
              }
          }
          else
          {
              if(f[e.v]>f[node]+e.y+1ll*e.g+e.y+1ll*e.r+e.y-temp)
              {
                  f[e.v]=f[node]+e.y+1ll*e.g+e.y+1ll*e.r+e.y-temp;
                  q.push({f[e.v],e.v});
              }
          }
      }
      for(auto &e:fan[node]) //此时属于反方向走,只有红灯的时候可以经过
      {
          ll temp=f[node]%(1ll*e.g+e.y+1ll*e.r+e.y);
          if(temp>=1ll*e.g+e.y&&temp<=1ll*e.g+e.y+e.r)//此时正处于红灯
          {
              if(f[e.v]>f[node]+e.y)
            {
                f[e.v]=f[node]+e.y;
                q.push({f[e.v],e.v});

            }
          }
          else if(temp<1ll*e.g+e.y)
          {
              if(f[e.v]>f[node]+1ll*e.y+e.g+e.y-temp)
              {
                  f[e.v]=f[node]+e.y+e.g+e.y-temp;
                  q.push({f[e.v],e.v});
              }
          }
          else
          {
              if(f[e.v]>f[node]+1ll*e.y+e.g+e.y+e.r+e.y-temp+e.g+e.y)
              {
                  f[e.v]=f[node]+e.y+e.g+e.y+e.r+e.y-temp+e.g+e.y;
                  q.push({f[e.v],e.v});
              }
          }
      }


  }
  if(f[t] == LONG_LONG_MAX / 2){ cout<<-1;}
  else {cout<<f[t];}
  return 0;
}

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据给出的试题来源,第十四届蓝桥杯大赛软件决赛,我们可以看到一系列字母和数字的组合。根据题目中的标识,我们可以做如下解释: pc-6:这可能表示参者的类别或背景,其中四个字母“pc”可能是某个组织或机构的缩写,后面的数字“6”可能是该组织或机构的编号或类别。 jc-6:同样地,这个组合可能是另一个参者的类别或背景,其中四个字母“jc”可能代表另一个组织或机构的缩写,后面的数字“6”可能是其编号或类别。 ja-4:这个组合代表第三个参者的类别或背景,其中四个字母“ja”可能表示另一个组织或机构的缩写,后面的数字“4”可能是其编号或类别。 jg-4:最后一个组合也代表一个参者的类别或背景,其中四个字母“jg”可能代表另一个组织或机构的缩写,后面的数字“4”可能是其编号或类别。 由于缺乏更多的背景信息,我们无法给出具体的解释。但可以推测这些字母和数字组合可能是用来标识参加蓝桥杯大赛软件决赛的不同参者,每个组合可能代表一个不同的参组织或机构,并有着各自的编号或分类。这种标识方法是为了方便组织者和参者进行管理和识别。 在蓝桥杯大赛软件决赛中,不同的参者将展示出他们的软件开发技能和能力,通过一系列的比环节,最终决出最优秀的软件开发团队或个人。这场比旨在鼓励和推动年轻人对软件开发的兴趣和热情,培养他们的创新思维和解决问题的能力,同时也为软件行业的发展和人才的选拔做出贡献。 总之,根据提供的信息,我们可以推测这些字符和数字组合可能是用来标识蓝桥杯大赛软件决赛的不同参者,同时也给出了关于大赛的一些背景和目的。这样的组合可以方便参者的管理和识别,同时也让人们更加了解这场竞的性质和意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值