hihoCoder #1041 : 国庆出游(DFS,bitset)

17 篇文章 0 订阅

#1041 : 国庆出游

时间限制: 1000ms
单点时限: 1000ms
内存限制: 256MB

描述

小Hi和小Ho准备国庆期间去A国旅游。A国的城际交通比较有特色:它共有n座城市(编号1-n);城市之间恰好有n-1条公路相连,形成一个树形公路网。小Hi计划从A国首都(1号城市)出发,自驾遍历所有城市,并且经过每一条公路恰好两次——来回各一次——这样公路两旁的景色都不会错过。


令小Hi苦恼的是他的小伙伴小Ho希望能以某种特定的顺序游历其中m个城市。例如按3-2-5的顺序游历这3座城市。(具体来讲是要求:第一次到达3号城市比第一次到达2号城市早,并且第一次到达2号城市比第一次到达5号城市早)。


小Hi想知道是否有一种自驾顺序满足小Ho的要求。

输入

输入第一行是一个整数T(1<=T<=20),代表测试数据的数量。

每组数据第一行是一个整数n(1 <= n <= 100),代表城市数目。

之后n-1行每行两个整数a和b (1 <= a, b <= n),表示ab之间有公路相连。

之后一行包含一个整数m (1 <= m <= n)

最后一行包含m个整数,表示小Ho希望的游历顺序。

输出

YES或者NO,表示是否有一种自驾顺序满足小Ho的要求。

样例输入
2
7
1 2
1 3
2 4
2 5
3 6
3 7
3
3 7 2
7
1 2
1 3
2 4
2 5
3 6
3 7
3
3 2 7
样例输出
YES
NO

 
   
#include<stdio.h>
#include<string.h>
#include<vector>
#include<bitset>
#include<algorithm>
using namespace std;
vector<int>u[105];
bitset<105>mp[105];
int flag[105][105],order[105];
int j,ok,n,m;
void find(int a,int v)
{
	mp[a][a]=1;
	for(int i=0;i<u[a].size();i++)
	{
		int b=u[a][i];
		if(b==v)
		continue;
		find(b,a);
	    mp[a]|=mp[b];
	}
}
void DFS(int a,int v)
{
	if(a==order[j])
	    j++;
	if(j==m)
	{
		ok=1;
		return ;
	}
	while(j<m)
	{
		int p=j,c=order[j];
		for(int i=0;i<u[a].size();i++)
		{
			int b=u[a][i];
			if(b==v)
			continue;
			if(mp[b][c]&&flag[a][b])
			{
				flag[a][b]=0;
				DFS(b,a);
				break;
			}
		 }
		 if(j==p) 
		   break; 
	}
}
int main()
{
	int t,a,b,i;
	scanf("%d",&t);
	while(t--)
	{
		ok=0;
		j=0;
		scanf("%d",&n);
		for(i=0;i<105;i++)
		{
			u[i].clear();
			mp[i].reset();
		}
		for(i=1;i<n;i++)
		{
			scanf("%d%d",&a,&b);
			u[a].push_back(b);
			u[b].push_back(a);
			flag[a][b]=flag[b][a]=1;
		}
		scanf("%d",&m);
		for(i=0;i<m;i++)
			scanf("%d",&order[i]);
		find(1,-1);
		DFS(1,-1);
		if(ok)
		{
			printf("YES\n");
		}
		else
		{
			printf("NO\n");
		}
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值