CodeForces 453C Little Pony and Summer Sun Celebration (dfs)

16 篇文章 0 订阅

 

题解: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;
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值