题目链接:点击打开链接
题意:
给定一个无向图
任选一个起点,使得访问每个点的次数奇偶与最后一行的输入一致
思路:
选一个奇数点作为起点
dfs树一下,若子节点不满足则先走到子节点再回来
如此就能保证所有子节点合法
这样dfs结束后最多只有根节点不满足,随便找一个与根相连的点调整一下。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h>
#include <queue>
#include <set>
#include <algorithm>
#include <stdlib.h>
using namespace std;
#define ll int
#define N 100005
#define inf 10000009
vector<int>G[N],ans, one, tmp;
int n, m;
int a[N], st, dis[N], pre[N];
void go(int u, int v, vector<int>&x){// v - u
x.push_back(v);
while(1){
v = pre[v];
x.push_back(v);
if(v==u)return ;
}
}
int vis[N], hehe[N];
void dfs(int u, int fa){
hehe[u] = fa;
ans.push_back(u);
vis[u] ^= 1;
for(int i = 0; i < G[u].size(); i++)
if(hehe[G[u][i]]==0)
{
dfs(G[u][i], u);
if(a[G[u][i]] != vis[G[u][i]])
{
ans.push_back(u);
ans.push_back(G[u][i]);
vis[G[u][i]]^=1;
vis[u] ^= 1;
}
if(ans[ans.size()-1] != u){ans.push_back(u); vis[u]^=1;}
}
}
void input(){
one.clear();
for(int i = 0; i <= n; i++)G[i].clear();
while(m--){
int u, v;
scanf("%d %d",&u,&v);
G[u].push_back(v); G[v].push_back(u);
}
st = -1;
for(int i = 1; i <= n; i++){
scanf("%d",&a[i]);
if(a[i])
{
if(st==-1)st = i;
one.push_back(i);
}
}
}
int main(){
int i, j, u, v;
while(~scanf("%d %d",&n,&m))
{
input();
if(st == -1) {puts("0");continue;}
if(one.size()==1){printf("1\n%d\n", st);continue;}
ans.clear();
memset(vis,0,sizeof vis);
memset(hehe, 0, sizeof hehe);
hehe[st] = st;
dfs(st, st);
if(a[st]!=vis[st]){
ans.push_back(G[st][0]);
ans.push_back(st);
ans.push_back(G[st][0]);
}
bool ok = false;
for(i = 1; i <= n; i++)if(a[i] && hehe[i] == 0)ok = true;
if(ok){puts("-1");continue;}
printf("%d\n",ans.size());
for(i = 0; i < ans.size(); i++)printf("%d ",ans[i]);puts("");
//memset(a, 0, sizeof a); for(i = 0; i < ans.size(); i++)a[ans[i]]^=1; for(i = 1; i <=n ;i++)printf("%d ", a[i]);puts("");
}
return 0;
}