785. 判断二分图
思路是填色。对于每个点,先将其填色1,放入队列。广搜的方式遍历对应的边的点,填上与之相反的颜色。如果有相同则false。反之为true;
882. 细分图中的可到达结点
在B站看了视频觉得就很清晰了。Dijkstra 算法.
思路是,求0到可以到每个点。但是可以先求0 到 n - 1节点的最短距离,在算maxMove除了到这个点还剩下多少步,就直接加进去。当然会有个重复的情况。比如0 ~ 1 距离5 ,假设0到1可走4,1到0可走3,结果应该去最小 min(5, 3 + 4);
PII -> pair<int,int>
分步讲讲代码:
定义一个vector< PII >adj[3000]
代表是每个节点(i)与之相邻节点需要的最短距离( PII )
先初始化,adj[e[0]].push_back({e[1] ,e[2] + 1});
别忘了是两个点以及距离权值是中间点数 + 1 。
定义一个小根堆priority_queue<PII,vector<PII>,greater<>> pq;
放入初始数据 {0 , 0}。
接下来就是BFS,注意每次取小根堆的点必须是最新的,也就是需要一个res数组记录这个点是否出现过。出现直接continue,反之记录,并且需要一个dist数组记录初始点到 cur 的最短距离。
循环这个adj[cur]相邻点,同样先判断res是否出现过。if(weight + d <= maxMoves)
这一步是判断是否超出,超出直接剪枝。反之记录进pq小根堆。
接下来就可以算出可以走到的点了。遍历每个点,先求起点sum = maxMove - dist[起点],还需要反过来计算终点sum,最后这俩按照上面说的,取最小。
除了中间值,还有自身,这个就很好算了,直接看res是否为1 就加。