zoukankan      html  css  js  c++  java
  • 【hiho1041】国庆出游 dfs+bitset

    题目大意:给定一棵 N 个节点的有根树,1 号节点为根节点,现遍历整棵树,要求每条边仅被经过两次,问是否存在一种特定的遍历方式使得 dfs 序中节点的相对前后关系符合给定的顺序。

    题解:
    首先,由于要求每条边仅能经过两次,可知若正在遍历当前节点 u,则以 u 为根节点的子树中的所有节点都必须遍历,因此遍历子树的顺序十分重要。我们可以提前预处理出树上每个节点能够到达以该节点为根的子树中的节点编号,并维护一个当前指针,指向给定顺序的序列,若某棵子树中有当前指针指向的点,则遍历该子树。

    代码如下

    #include <bits/stdc++.h>
    #define pb push_back
    using namespace std;
    const int maxn=110;
    
    vector<int> G[maxn];
    bitset<maxn> f[maxn];
    int n,m,go[maxn],now;
    bool vis[maxn];
    
    void dfs1(int u,int fa){
    	f[u][u]=1;
    	for(auto v:G[u]){
    		if(v==fa)continue;
    		dfs1(v,u);
    		f[u]|=f[v];
    	}
    }
    bool dfs2(int u){
    	if(u==go[now])++now;
    	if(now==m+1)return 1;
    	vis[u]=1;
    	while(1){
    		bool has=0;
    		int need=go[now];
    		for(auto v:G[u]){
    			if(vis[v])continue;
    			if(f[v][need]){
    				has=1;
    				if(dfs2(v))return 1;
    			}
    		}
    		if(!has)return 0;
    	}
    	return 0;
    }
    void read_and_parse(){
    	scanf("%d",&n);
    	for(int i=1;i<n;i++){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		G[x].pb(y),G[y].pb(x);
    	}
    	scanf("%d",&m);
    	for(int i=1;i<=m;i++)scanf("%d",&go[i]);
    }
    void solve(){
    	dfs1(1,0);
    	now=1;
    	puts(dfs2(1)?"YES":"NO");
    }
    void init(){
    	for(int i=1;i<=n;i++)G[i].clear(),f[i].reset();
    	memset(vis,0,sizeof(vis));
    }
    int main(){
    	int T;scanf("%d",&T);
    	while(T--){
    		init();
    		read_and_parse();
    		solve();
    	}
    	return 0;
    }
    
  • 相关阅读:
    Python -- Redis List
    Python --Redis Hash操作
    Python使用redis介绍
    缓存服务器
    linux python3获取ip地址
    Rabbitmq -- rpc
    Rabbitmq--topic
    Rabbitmq -- direct
    删除rabbitmq中持久化的队列和数据
    Exchange-fanout 广播模式
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10944324.html
Copyright © 2011-2022 走看看