题目链接:Codeforces 453 Little Pony and Summer Sun Celebration
题目大意:n个节点,m条边,然后m行给定边,最后一行表示每个节点需要进过的次数为奇数次还是偶数次。
解题思路:构造,任意从一个奇数点开始(统一森林的处理),然后每次向下遍历没有经过的节点,并且回溯,每次回溯都要判断一下刚才走过的点满不满足条件,不满足的话就再走一次。最后对于根节点,最后一次回溯要不要走根据当前走过的次数决定。
注意点:此题并不要求走的步数最少
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn = 1e5+5;
vector<int> vv[maxn];
int num[maxn];
int ans[maxn*4];
int n,m,s,k;
int v[maxn];
void set_index(int u)
{
num[u]^=1;
ans[k++] = u;
}
void dfs(int u)
{
set_index(u);
v[u] = 1;
for(int i =0;i<vv[u].size();i++)
{
if(v[vv[u][i]]) continue;
dfs(vv[u][i]);
set_index(u);
if(num[vv[u][i]])
{
set_index(vv[u][i]);
set_index(u);
}
}
}
bool judge()
{
for(int i =0;i<=n;i++)
if(num[i])
return false;
return true;
}
int main()
{
cin >> n >> m;
int a,b;
k = s =0;
for(int i =0;i<m;i++)
{
cin >> a >> b;
vv[a].push_back(b);
vv[b].push_back(a);
}
for(int i=1;i<=n;i++)
{
cin >> num[i];
if(num[i]&1)
s = i;
}
dfs(s);
if(num[s])
{
num[s] = 0;
k --;
}
if(judge())
{
cout<<k <<endl;
if (k)
{
cout<< ans[0] << " " ;
for (int i = 1; i <k; i++)
cout<< ans[i] << " " ;
cout << endl;
}
}
else
cout << "-1" << endl;
return 0;
}