C++ 【LeetCode WeeklyContest 146】1129. Shortest Path with Alternating Colors【BFS】

题目:

求有向图中从起点0到其他节点的最短路径,有自环,有平行边。
函数接口:

vector shortestAlternatingPaths(int n, vector>& red_edges, vector>& blue_edges) { 

}

思路:

BFS求最短路

具体实现:

由于题目中引入了红蓝边,且交替的才算路径,这样每个节点都有可能作为红边或者蓝边的起点(终点),这样在引入存储该有向图的数据结构-邻接表时,除了节点本身的索引值,还需要额外存储该节点的颜色属性,红色0,蓝色1。

vector>> g(n); // 邻接节点,颜色

接下来将图信息导入到g中。

for(auto &r : red_edges) g[ r[0] ].push_back( {r[1], 0} ); 
for(auto &b : blue_edges) g[ b[0] ].push_back( {b[1],1} );

然后,初始化起点到各节点的最短路径向量vCost,不可达或者未访问用-1来表示,这里要注意,对于环路的考虑,因为是BFS,所以当前最短路径确定后,以后由于环路而再次访问该节点时,肯定不是最短路径。
因为每个节点可能是红或蓝边的终点,所以可能存在两条红蓝交替而来的最短路径,故vCost每个节点应存储红蓝两个维度的最短路径,而最终返回二者最短的那个,当然是在最短路径存在的前提下。

vector> vCost(n, vector(2,-1));

再初始化用来BFS的队列q,队列元素存储的信息应包括:当前访问的索引值,当前索引指向的节点作为边终点的颜色。

queue> q;

作为起点0,既可以是红边的终点,也可以是蓝边的。所以初始化队列应这样:

q.push({0,0});
q.push({0,1});

而起点0到本身的最短路径长度应为0,故:

vCost[0] = {0,0};

接着BFS图g, 将最短路径存储到vCost:

while(!q.empty())
{
	auto [i, c1] = q.front(); q.pop(); // i = current index, c1 = the color of the last line
	for( auto [j, c2] : g[i]) {
		if( vCost[j][c2]!=-1 || c1==c2 ) continue; // 当前节点之前访问过了 或者 该边同上一条边颜色相同
		vCost[j][c2] = vCost[i][c1] +1;
		q.push({j,c2});
	}
}

由于vCost中存储的是两条路线的最短路径,根据题目要求应返回最短的那一条。

vector res;
for( auto & v : vCost ) {
	sort(v.begin(),v.end());
	res.push_back(v[0]==-1? v[1]:v[0]);
}
return res;

参考代码:https://leetcode.com/problems/shortest-path-with-alternating-colors/discuss/341474/C%2B%2B-bfs

你可能感兴趣的:(LeetCode)