要使所有城市x都要能到达0城,则必须让从0->x的路径上的所有边,都指向0城来的方向,以0到2为例,路径为(0,1,3,2)。
- 0指向1,1不能到达0,需要反转。
- 1指向3,3不能到达1,需要反转。
- 2指向3,2能够到达3,不需要反转。
因此首先要能够找到一条从0和其他城市之间的路径,此处可以采用dfs。
每遍历到一个城市,如果它的子节点的边不指向它,那么就让这条边反转,然后就可以继续往下遍历了。
这样如果从0遍历到v,能够始终保持v能够到达0,只要使得v的子节点也能到达0,到叶子节点时,就符合了题目的要求。
class Solution {
public:
// 要把所有不指向0的边都反过来
int ans = 0;
vector<vector<pair<int, int>>> edges; // 邻接链表
int minReorder(int n, vector<vector<int>>& connections) {
edges = vector<vector<pair<int, int>>>(n);
for(auto &con : connections){
int u = con[0], v = con[1];
edges[u].push_back({v, 1}); // 1代表是从u指向v的,0代表是v指向u的。如果从0节点开始遍历,遇到了0->other的点,需要反转
edges[v].push_back({u, 0});
}
dfs(0, -1);
return ans;
}
void dfs(int u, int fa){
for(auto &edge : edges[u]){
int v = edge.first, dir = edge.second;
if(v == fa)continue; // 父节点,不需要遍历
if(dir == 1)ans++; // 这表示v->u,但是0->u,因此如果想要0->u->v,必须让这条线反转
dfs(v, u); // 继续遍历
}
}
};