带信号灯的最短路问题(c++)

运筹与优化试题(c++版本)

带信号灯的最短路问题

  1. 题目描述
    现在城市有N个路口,每个路口有自己的编号,从0到N-1,每个路口还有自己的交通控制信号,例如0,3表示0号路口的交通信号每3个时刻变化一次,即0到3时刻0号路口允许通过,3到6时刻不允许通过,而6到9时刻又允许通过;以此类推,所有路口的允许通行都从时刻0开始。同时城市中存在M条道路将这N个路口相连接起来,确保从一个路口到另一个路口都可达,每条路由两个端点加上通行所需要的时间表示。现在给定起始路口和目的路口,从0时刻出发,请问最快能在什么时刻到达?
  • 代码

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    int min_time = INT_MAX;
    void dfs(vector<vector<int>> dist_time,int N,vector<int> signal,int s,int t,int sum,vector<int> mark) {
        //到达目的地节点,判断是否更新最小值
        if(s == t)
        {
            if(min_time > sum)
            {
                min_time = sum;
            }
        }
        for(int k = 0;k < N;k++)
        {
            //该节点未经过且可抵达
            if(mark[k] == 0 && dist_time[s][k] < INT_MAX)
            {
                int wait = 0;
                //到达目的地不需要等待,否则根据当前时间更新等待时间
                if(k != t &&(sum + dist_time[s][k]) % (signal[k] * 2) > signal[k])
                {
                    wait = signal[k] * 2 - ((sum + dist_time[s][k]) % (signal[k] * 2));
                }
                mark[k] = 1;
                //深度搜索
                dfs(dist_time,N,signal,k,t,sum + dist_time[s][k] + wait,mark);
                mark[k] = 0;
            }
        }
        return; }
    
    int main() {
        int M,N;//总的路口数
        cout << "输入路口数目:" << endl;
        while(cin >> N)
        {
            //初始化信号灯控制信号
            vector<int> signal(N,0);
            cout << "输入信号灯矩阵" <<endl;
            int node,item;
            for(int i = 0;i < N;i++)
            {
                cin >> node >> item;
                signal[node] = item;
            }
    
            vector<vector<int>> dist_time(N,vector<int> (N,INT_MAX));
            cout << "输入道路总数:" << endl;
            cin >> M;
            cout << "输入距离矩阵:" << endl;
            for(int i = 0;i < M;i++)
            {
                int x,y;
                cin >> x >> y >> item;
                dist_time[x][y] = item;
                dist_time[y][x] = item;
            }
            cout << "最终结果" <<endl;
            for(int i = 0;i < N;i++)
            {
                for(int j = 0;j < N;j++)
                {
                    if(j !=  i)
                    {
                        min_time = dist_time[i][j];
                        vector<int> mark(N,0);
                        mark[i] = 1;
                        dfs(dist_time,N,signal,i,j,0,mark);
                        cout << i + 1 << " " << j + 1 << " " << min_time << endl;
                    }
                }
            }
            system("pause");
        } } 
    
    
  • 测试

  • 6
    0 16
    1 17
    2 15
    3 17
    4 18
    5 14
    9
    0 1 66
    0 2 80
    0 3 50
    1 4 78
    1 5 90
    1 2 30
    2 3 45
    2 5 81
    4 5 76

  • 结果

  • 1 2 66
    1 3 80
    1 4 50
    1 5 146
    1 6 158
    2 1 66
    2 3 30
    2 4 75
    2 5 78
    2 6 90
    3 1 80
    3 2 30
    3 4 45
    3 5 112
    3 6 81
    4 1 50
    4 2 75
    4 3 45
    4 5 153
    4 6 126
    5 1 144
    5 2 78
    5 3 108
    5 4 165
    5 6 76
    6 1 168
    6 2 90
    6 3 81
    6 4 135
    6 5 76

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值