题解:https://blog.csdn.net/keshuai19940722/article/details/38352623
看完上面这篇题解,写出来了这道搜索题,思路基本都来自上面这篇题解
- 用answer[]数组来记录所要输出的路径(答案),visit[]标记该节点是否访问过
- 用condition[]记录每个节点的访问状态
- 定义一个record数组:访问该节点,把他的访问状态置为相反,把该节点放入answer[]数组记录下来
- dfs,访问父亲节点,遍历每个子节点,对于每个未访问过的子节点都dfs一遍,回到父亲节点,如果该子节点的状态不符合题意,就再次访问子节点(此时不dfs),回到父亲节点
- main函数中,把m条边,n个点的访问次数读进来。如果是奇数访问次数的节点初始状态为false,需要访问奇数次才能变为true.而偶数访问次数的节点需要访问偶数次,或者不访问达到true状态
- first是第一个访问次数为奇数的节点,用first开始访问。first初始值为0;
- 如果first节点的状态在dfs之后不满足题意,那么一开始就不访问first,忽略它
- 当dfs后所有的节点都是true状态时,输出结果
- 如果first的值仍为0,说明所有节点的访问次数都是偶数,那么所有节点都不访问。
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 100000
int answer[maxn*4+10],visit[maxn+10];
bool condition[maxn+10];
int cnt;
vector<int>child[maxn+10];
void record(int node)
{
if(condition[node]==true)
condition[node]=false;
else
condition[node]=true;
answer[cnt++]=node;
}
void dfs(int node)
{
//printf("dfs(%d)\n",node);
record(node);
visit[node]=1;
for(int i=0;i<child[node].size();i++)
{
if(!visit[child[node][i]])
{
//printf("%d:%d\n",child[node][i],visit[child[node][i]]);
dfs(child[node][i]);
record(node);
if(condition[child[node][i]]==false)
{
//printf("***%d:%d\n",child[node][i],visit[child[node][i]]);
record(child[node][i]);
record(node);
}
}
}
}
int main()
{
int n,m,x,y,first=0;
scanf("%d %d",&n,&m);
for(int i=0;i<m;i++)
{
scanf("%d %d",&x,&y);
child[x].push_back(y);
child[y].push_back(x);
}
bool d=false;
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
if(x==1)
{
if(d==false)
{
first=i;
d=true;
}
//first=i;
condition[i]=false;
}
else if(x==0)
condition[i]=true;
}
cnt=0;
dfs(first);
if(condition[first]==false)
{
condition[first]=true;
cnt--;
}
bool what=true;
for(int i=1;i<=n;i++)
{
if(condition[i]==false)
{
what=false;
break;
}
}
if(what==false)
printf("-1\n");
else
{
if(cnt==0||first==0)//所有节点全部是偶数访问次数,不访问了
printf("0\n");
else
{
printf("%d\n",cnt);
for(int i=0;i<cnt;i++)
{
if(i!=cnt-1)
printf("%d ",answer[i]);
else
printf("%d\n",answer[i]);
}
}
}
return 0;
}