J - J HihoCoder - 1041

小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的要求。
Input
输入第一行是一个整数T(1<=T<=20),代表测试数据的数量。
每组数据第一行是一个整数n(1 <= n <= 100),代表城市数目。
之后n-1行每行两个整数a和b (1 <= a, b <= n),表示ab之间有公路相连。
之后一行包含一个整数m (1 <= m <= n)
最后一行包含m个整数,表示小Ho希望的游历顺序。
Output
YES或者NO,表示是否有一种自驾顺序满足小Ho的要求。
Sample Input
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
Sample Output
YES
NO

#include<stdio.h>
#include<bitset>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 111 
vector<int> road[N];
int flag[N][N];
int order[N];
bitset<N> digit[N];
int ok,j,m;
void work(int a,int v)
{
	digit[a][a]=1;
	for(int i=0;i<road[a].size();i++)
	{
		int b=road[a][i];
		if(b==v)
		continue;
			work(b,a);
		digit[a]|=digit[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<road[a].size();i++)
		{
			int b=road[a][i];
			if(b==v)
			continue;
			if(digit[b][c]&&flag[a][b])
			{
				flag[a][b]=0;
				dfs(b,a);
				break;
			}
		}
		if(p==j)
		break;
	}
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
       int n;
       ok=j=0; 
       memset(flag,0,sizeof(flag));  
        for(int i=0;i<N;i++)  
        {  
            digit[i].reset();
            road[i].clear();  
        }  

	   scanf("%d",&n);
	   for(int i=1;i<n;i++)
	   {
	   	    int a,b;
	   	    scanf("%d %d",&a,&b);
	   	    road[a].push_back(b);
	   	    road[b].push_back(a);
	   	    flag[a][b]=1;flag[b][a]=1;
	   }
	   scanf("%d",&m);
	   int oo=1;  
	   for(int i=0;i<m;i++)
	   {
	   	scanf("%d",&order[i]);

	   }		
		work(1,-1);	 
		
	/*	for(int i=0;i<m;i++)
		{
			int ok=0;
			for(int j=i+1;j<m;j++)
			{
				if(!digit[order[i]][order[j]]&&!digit[order[j]][order[i]])
				ok=1;
				else if(!digit[order[i]][order[j]]&&digit[order[j]][order[i]])
				{
				oo=0;break;
			   }
				else if(digit[order[i]][order[j]])
				{
					if(ok==1)
					oo=0;
				}
			}
		 } 
		 if(oo==1)
		 printf("YES\n");
		 else
		 printf("NO\n");*/
		 dfs(1,-1);
		 if(ok)
		 printf("YES\n");
		 else
		 printf("NO\n");
	}
	return 0;
 } 

猜你喜欢

转载自blog.csdn.net/liuliu2333/article/details/80767795
J
3 J