挺好的一道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;
}