Official

G - Unique Walk Editorial by en_translator


Consider dividing the vertices of \(G\) into connected component considering only the edges not belonging to \(S\). Then consider a graph \(G'\) whose vertices correspond to the connected components and where there is an edge between the vertices corresponding to the connected components that \(U_{x_i}\) and \(V_{x_i}\) belong, for each edge \(x_i\) in \(S\). Here, \(G'\) is a connected undirected graph, but not necessarily simple.

For a walk on \(G\), consider another walk on \(G'\) which uses the edges in \(S\) used in \(G\) in order. (Note that as long as an edge not belonging to \(S\) is used, we stay in the same vertex in \(G'\).) Since this path uses every edge of \(G'\) exactly once, this is an Eulerian trail on \(G'\). Thus, if \(G'\) does not have an Eulerian trail, i.e. if \(G'\) is neither an Eulerian nor semi-Eulerian graph, then such a walk does not exist.
On the other hand, if \(G'\) has an Eulerian trail, then a desired walk always exists and constructed as follows. For an arbitrary Eulerian trail on \(G'\), consider a sequence of edges belonging to \(S\) (in \(S\)) that correspond to those edges in the order of the trail, giving them a direction to each of them in the order of passing through; then, for any contiguous two edges in the sequence, the end of the former edge and the starting point of the latter belongs to the same connected component (that we considered the edges not belonging to \(S\)). If two vertices belong to the same connected component, we can travel between them freely. By taking such a path and connecting the edges belonging to \(S\), one can construct a conforming trail from an Eulerian trail.

Thus, it is sufficient to generate \(G'\) and check if an Eulerian trail exist. By Euler’s theorem, an Eulerian trail exists if and only if there are zero or two vertices with odd degrees. Since \(G'\) can be generated (by determining the connected components when only edges not belonging to \(B\) exist) in an \(O(N+M)\) time, and checking the parity of the degree a vertex on \(G'\) can also done in a total of \(O(N+M)\). Hence, the problem has been solved.

Sample code (C++):

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

int idx;
int c[N];
vector<int>e[N];

void dfs(int cur){
	c[cur]=idx;
	int sz=e[cur].size();
	for(int i=0;i<sz;i++)if(c[e[cur][i]]==-1)dfs(e[cur][i]);
	return;
}
 
int main() {
	int n,m,k,x;
	int u[N],v[N];
	bool a[N];
	int cnt[N];
	int odd;

	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>u[i]>>v[i];
		u[i]--,v[i]--;
	}
	for(int i=0;i<m;i++)a[i]=false;
	cin>>k;
	for(int i=0;i<k;i++){
		cin>>x;
		a[x-1]=true;
	}

	for(int i=0;i<m;i++){
		if(!a[i]){
			e[u[i]].push_back(v[i]);
			e[v[i]].push_back(u[i]);
		}
	}

	for(int i=0;i<n;i++)c[i]=-1;
	idx=0;
	for(int i=0;i<n;i++){
		if(c[i]==-1){
			dfs(i);
			idx++;
		}
	}

	for(int i=0;i<idx;i++)cnt[i]=0;
	for(int i=0;i<m;i++){
		if(a[i]){
			cnt[c[u[i]]]++,cnt[c[v[i]]]++;
		}
	}
  
	odd=0;
	for(int i=0;i<idx;i++)if(cnt[i]%2)odd++;
	if(odd<=2)cout<<"Yes"<<endl;
	else cout<<"No"<<endl;
	return 0;
}

posted:
last update: