力扣1129 颜色交替的最短路径

前言

最近数据结构学习刚进入图论,所以刷了一道图论题,暴力解法,实力很菜。

题目

思路

求最短路径率先想到了使用bfs(深度优先遍历)解决,于是在不断出错修改出错修改下,完成了这道题。

因为是红蓝交替的最短路径,所以分为两种,一种是:红蓝红蓝红蓝......另一种是:蓝红蓝红蓝红......所以要进行两次dfs遍历,分别是以红为起点和以蓝为起点。作为dfs遍历的过程中的容器,我使用一个队列,每层之间用-1分隔,并用两个布尔变量,red和blue来确定当前层应该在红路径找还是蓝路径找,但这里的red和blue分别是用于红为起点和蓝为起点两次dfs遍历。cnt_red和cnt_blue分别用于记录以红为起点和以蓝为起点的当前层数。两个布尔数组Rvisited和Bvisited分别用于记录以蓝为起点和以红为起点bfs遍历时,分别以红蓝为入度的结点是否被访问过,被访问过就不再访问。过程过于暴力,成绩惨不忍睹,不过,好歹花了一下午在这上面,记录一下!

class Solution {
public:
    vector<int> shortestAlternatingPaths(int n, vector<vector<int>>& redEdges, vector<vector<int>>& blueEdges)
    {
        int cnt_red = 0, cnt_blue = 0;
        queue<int> que; que.push(-1); que.push(0);
        bool red = 0, blue = 0;
        vector<vector<bool>> Rvisited(n, vector<bool>(2, 0)), Bvisited(n, vector<bool>(2, 0));
        Rvisited[0][0] = 1; Bvisited[0][1] = 1;
        vector<int> answer(n, -1); answer[0] = 0;
        while (!que.empty())
        {
            if (que.front() == -1)
            {
                que.pop();
                ++cnt_red;
                if (que.empty()) break;
                que.push(-1);
                red = !red;
            }
            int obj = que.front();
            que.pop();
            if (red)
            {
                for (int i = 0; i < redEdges.size(); ++i)
                {
                    int temp = redEdges[i][1];
                    if (redEdges[i][0] == obj && Rvisited[temp][0] == 0)
                    {
                        que.push(temp);
                        Rvisited[temp][0] = 1;
                        if (answer[temp] == -1) answer[temp] = cnt_red;
                    }
                }
            }
            else
            {
                for (int i = 0; i < blueEdges.size(); ++i)
                {
                    int temp = blueEdges[i][1];
                    if (blueEdges[i][0] == obj && Rvisited[temp][1] == 0)
                    {
                        que.push(temp);
                        Rvisited[temp][1] = 1;
                        if (answer[temp] == -1) answer[temp] = cnt_red;
                    }
                }
            }
            
        }
        que.push(-1); que.push(0);
        while (!que.empty())
        {
            if (que.front() == -1)
            {
                que.pop();
                ++cnt_blue;
                if (que.empty()) break;
                que.push(-1);
                blue = !blue;
            }
            int obj = que.front();
            que.pop();
            if (blue)
            {
                for (int i = 0; i < blueEdges.size(); ++i)
                {
                    int temp = blueEdges[i][1];
                    if (blueEdges[i][0] == obj && !Bvisited[temp][1])
                    {
                        que.push(temp);
                        Bvisited[temp][1] = 1;
                        if (answer[temp] == -1 || answer[temp] > cnt_blue) answer[temp] = cnt_blue;
                    }
                }
            }
            else
            {
                for (int i = 0; i < redEdges.size(); ++i)
                {
                    int temp = redEdges[i][1];
                    if (redEdges[i][0] == obj && !Bvisited[temp][0])
                    {
                        que.push(temp);
                        Bvisited[temp][0] = 1;
                        if (answer[temp] == -1 || answer[temp] > cnt_blue) answer[temp] = cnt_blue;
                    }
                }
            }
            
        }
        return answer;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值