题目链接:Little Pony and Summer Sun Celebration
这题其实就是要构造一条路径满足每个点访问的奇偶性满足题目给出的条件。发现如果想改变当前点的奇偶性只要先访问另外一个点再回来就可以了,然后只要dfs一次,但是起点从哪开始以及如何回溯都没有想明白..
后来看了别人的题解,dfs过程中记录每个点,并且回溯也记录下来,每次回溯的时候检查一下刚才这个点是否满足奇偶性,这样下来最后回溯到起点,只有起点可能不满足,如果起点不满足,只需要走到相邻一个点,再走回来再走到那个点就可以了(更方便的方法就是直接退回去不再走起点)。
改变奇偶性可以用^1来完成。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
#define N 100010
vector<int>G[N];
int ans[N*4];
bool vis[N],c[N];
int cnt;
void v(int x){
ans[cnt++]=x;
c[x]^=1;
}
void dfs(int x){
vis[x]=1;
v(x);
for(int i=0;i<G[x].size();i++){
if(vis[G[x][i]]) continue;
dfs(G[x][i]);
v(x);
if(c[G[x][i]]){
v(G[x][i]);
v(x);
}
}
}
bool judge(int n){
for(int i=1;i<=n;i++) if(c[i]) return false;
return true;
}
int main()
{
int n,m,u,v;
cnt=0;
memset(vis,0,sizeof(vis));
cin>>n>>m;
for(int i=0;i<m;i++){
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
int st=-1;
for(int i=1;i<=n;i++){
scanf("%d",&u);
c[i]=u;
if(st==-1&&u){
st=i;
}
}
dfs(st);
if(c[st]){
c[st]=0;
cnt--;
}
if(judge(n)){
printf("%d\n",cnt);
for(int i=0;i<cnt;i++){
printf("%d ",ans[i]);
}
printf("\n");
}
else printf("-1\n");
return 0;
}