Official

C - Simple path Editorial by en_translator


There are several ways to find a path on a tree; here, we introduce ways using DFS and a stack.

A DFS (Depth-First Search) on a graph is a method to enumerate all vertices traversable from vertex \(S\) along the edges by repeating the following sequence of operations. Here, we need to maintain \(flag[v]\), signifying whether you visited each vertex \(v\) or not. Initially, \(flag[v]=False\) for all vertex.

  1. For the current vertex \(v\), let \(flag[v]=True\).
  2. Choose a vertex \(w\) that can be directly moved from \(v\) which you have not visited yet, that is, where \(flag[w]=False\). Move to \(w\) and start over from \(1.\)
  3. If there is no such vertex in \(2.\), if the current vertex is the starting vertex \(S\), exit the search. Otherwise, return to the vertex that you visited right before you visited the current vertex for the first time, and resume \(2.\).

In order to find the sequence of vertices on the path, it is sufficient to start from vertex \(X\) and repeat the following sequence of operations that is a modified version of the one we described before. Initially, the deque is empty.

  1. Append \(v\) to the tail of the deque.
  2. For the current vertex \(v\), let \(flag[v]=True\).
  3. Choose a vertex \(w\) that can be directly moved from \(v\) which you have not visited yet, that is, where \(flag[w]=False\). Move to \(w\) and start over from \(1.\)
  4. Remove the last element from the tail of the deque. (Here, \(v\) itself is removed.)
  5. If there is no such vertex in \(3.\), if the current vertex is the starting vertex \(X\), exit the search. Otherwise, return to the vertex that you visited right before you visited the current vertex for the first time, and resume \(3.\).

The problem can be answered by outputting the contents of the deque from the initial element right after vertex \(Y\) is appended to the tail of the deque.

First, this is a path from vertices \(X\) to \(Y\). Moreover, step \(1.\) is never executed twice for the same vertex in the DFS, so this is a simple path. Here, we know that there is a unique simple path on a tree, so this is the answer.

There are many other ways to find it. For example, we can assume that the tree is rooted at \(Y\) and repeat going back from vertex \(X\) to its parent, then we obtain a simple path.

Sample code in C++:

#include <bits/stdc++.h>
using namespace std;

vector<int>e[200010];
bool flag[200010];
deque<int> deq;
bool stop;
 
void dfs(int k,int to){
	if(!stop)deq.push_back(k);
	if(k==to)stop=true;
    flag[k]=true;
	int sz=e[k].size();
    for(int i=0;i<sz;i++){
        if(!flag[e[k][i]])dfs(e[k][i],to);
    }
	if(!stop)deq.pop_back();
	return;
}

int main(void) {
    int n,x,y;
    int u,v;

	cin>>n>>x>>y;
    for(int i=0;i<n-1;i++){
		cin>>u>>v;
		e[u].push_back(v);
		e[v].push_back(u);
    }

    for(int i=1;i<=n;i++)flag[i]=false;
    stop = false;
 dfs(x,y);

    while(!deq.empty()){
		cout<<deq.front();
		deq.pop_front();
		if(deq.empty())cout<<endl;
		else cout<<" ";
	}
	return 0;
}

posted:
last update: