ZOJ1376 POJ1227 RoboContest,DFS

挺好的一道DFS题。

题目给定一个无向图,节点上放置有机器人,要求每一个回合机器人都要往相邻的节点走一步,问是否存在有一个节点,使得所有机器人在某一步中能够在此节点相会。

假如对于其中一个机器人,在某个节点上,在奇数步odd内能够到达此节点,则在任意比odd大的奇数步内都能重返此节点。偶数步同理也是。

需要注意的是,有些节点不管是奇数还是偶数都能到达。

因此,对于每一个机器人,我们只需要用DFS探索它对于每一个节点,奇数步和偶数步的到达情况,最后统计是否有节点满足对于所有机器人都能奇数步到达或者偶数步到达,即可。

#ifdef _MSC_VER
#define DEBUG
#define _CRT_SECURE_NO_DEPRECATE
#endif

#include <fstream>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#include <limits.h>
#include <algorithm>
#include <math.h>
#include <numeric>
#include <functional>
#include <ctype.h>
#include <vector>
#define MAX 110
using namespace std;

vector<int> map[MAX];
bool odd[MAX],even[MAX];
int odd_count[MAX],even_count[MAX];

void init(const int &n)
{
	for(int i=0;i<MAX;++i)
		map[i].clear();
	memset(odd_count,0,sizeof(odd_count));
	memset(even_count,0,sizeof(even_count));
}

void dfs(const int &x,const int &step)
{
	bool flag=false;
	if( !odd[x] && step%2)
	{
		flag=true;
		odd[x]=true;
	}
	if( !even[x] && step%2==0)
	{
		flag=true;
		even[x]=true;
	}
	if(flag)
	{
		for(size_t i=0;i<map[x].size();++i)
			dfs(map[x][i],step+1);
	}
}

int main(void)
{
#ifdef DEBUG  
	freopen("../stdin.txt","r",stdin);
	freopen("../stdout.txt","w",stdout); 
#endif  

	int n,m,ncase=1;
	int id,u,v,tmp;
	scanf("%d",&ncase);

	while(ncase--)
	{
		scanf("%d%d",&n,&m);
		init(n);
		for(int i=0;i<n;++i)
		{
			scanf("%d%d",&id,&tmp);
			for(int j=0;j<tmp;++j)
			{
				scanf("%d",&v);
				map[id].push_back(v);
			}
		}
		for(int i=0;i<m;++i)
		{
			memset(odd,false,sizeof(odd));
			memset(even,false,sizeof(even));
			scanf("%d",&u);
			dfs(u,0);
			for(int j=0;j<MAX;++j)
			{
				if(odd[j])
					++odd_count[j];
				if(even[j])
					++even_count[j];
			}
		}
		bool ans=false;
		for(int i=0;i<MAX && !ans;++i)
		{
			if(odd_count[i]==m)
				ans=true;
			if(even_count[i]==m)
				ans=true;
		}
		if(ans)
			printf("YES\n");
		else
			printf("NO\n");
	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值