这道题可以用DFS和BFS分别完成。
要说DFS和BFS讲的透彻的,还是算法导论,下面给出算法导论上的伪代码,注意,其中任何一行code都是非常值得玩味的:
BFS伪代码
BFS(G, s)
1 for each vertex u ∈ V [G] - {s}
2 do color[u] ← WHITE
3 d[u] ← ∞
4 π[u] ← NIL
5 color[s] ← GRAY
6 d[s] ← 0
7 π[s] ← NIL
8 Q ← ?
9 ENQUEUE(Q, s)
10 while Q ≠ ?
11 do u ← DEQUEUE(Q)
12 for each v ∈ Adj[u]
13 do if color[v] = WHITE
14 then color[v] ← GRAY
15 d[v] ← d[u] + 1
16 π[v] ← u
17 ENQUEUE(Q, v)
18 color[u] ← BLACK
当图中有环的时候,可能出现重复访问的情况,这时用color着色,防止重复访问已经访问过的节点。其实关键是Gray和White,Black就是标记这个节点是不是完全被访问完成了。
注意,之前访问过的节点根本不能进入队列。
DFS伪代码
DFS(G)
1 for each vertex u ∈ V [G]
2 do color[u] ← WHITE
3 π[u] ← NIL
4 time ← 0
5 for each vertex u ∈ V [G]
6 do if color[u] = WHITE
7 then DFS-VISIT(u)
DFS-VISIT(u)
1 color[u] ← GRAY
2 time ← time +1
3 d[u] <-time
4 for each v ∈ Adj[u]
5 do if color[v] = WHITE
6 then π[v] ← u
7 DFS-VISIT(v)
8 color[u] <-BLACK
9 f [u] ? time ← time +1
注意,也用着色来避免重复访问,关键也是Gray和White。当一个节点之前被访问过的情况下,无法递归调用DFS-VISIT。
另外,我们平时在写DFS的时候,尽量脑子只思考两层,第一层for循环,第二层递归,否则很容易晕。
BFS代码:
unordered_map<UndirectedGraphNode*,UndirectedGraphNode *> mp; unordered_map<UndirectedGraphNode*,bool> color; UndirectedGraphNode * bfs(UndirectedGraphNode *node){ if(node==NULL) return NULL; UndirectedGraphNode * root=new UndirectedGraphNode(node->label); mp[node]=root; queue<UndirectedGraphNode *> Q; Q.push(node); color[node]=true; while(!Q.empty()){ UndirectedGraphNode * front=Q.front(); Q.pop(); for(int i=0;i<front->neighbors.size();i++){ if(color[front->neighbors[i]]!=true){ Q.push(front->neighbors[i]); color[front->neighbors[i]]=true; UndirectedGraphNode * temp=new UndirectedGraphNode(front->neighbors[i]->label); mp[front->neighbors[i]]=temp; mp[front]->neighbors.push_back(temp); } else{ mp[front]->neighbors.push_back(mp[front->neighbors[i]]); } } } return root; } UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { return bfs(node); }
unordered_map<UndirectedGraphNode*,UndirectedGraphNode *> mp; unordered_map<UndirectedGraphNode*,bool> color; UndirectedGraphNode * dfs(UndirectedGraphNode *node,UndirectedGraphNode *parent){ if(node==NULL) return NULL; UndirectedGraphNode * me=NULL; color[node]=true; if(mp[node]==0){ me=new UndirectedGraphNode(node->label); mp[node]=me; } else{ me=mp[node]; } if(parent!=NULL) parent->neighbors.push_back(me); for(int i=0;i<node->neighbors.size();i++){ if(color[node->neighbors[i]]==true) me->neighbors.push_back(mp[node->neighbors[i]]); if(color[node->neighbors[i]]!=true) dfs(node->neighbors[i],me); } return me; } UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { return dfs(node,NULL); }
原文地址:http://blog.csdn.net/ffmpeg4976/article/details/44903825