zoj 3811 条件下判定某遍历序列的合法性/ 一遍 dfs

题意:在某些点上安装首次访问时候会报警的机器,给出报警嗲你的顺序,问是否合法。

思路:按所给的序列,每个进来时判断这个点目前能否达到(第一个可达总是),若能,则该点进行扩展遍历所有没有报警器的点,遇到有的报警器的标记可达就返回。

预判:判断原图连图性。

#include<iostream>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
vector<vector<int> >g(100010);
int has[100010];
vector<int>jud;
int n,m,k,l;
int vis[100010];
bool bfs()
{
    memset(vis,0,sizeof(vis));
    queue<int>q;
    q.push(1);
    vis[1]=1;
    while(!q.empty())
    {
        int cur=q.front();
        q.pop();
      for(int i=0;i<g[cur].size();i++)
      {
        int v=g[cur][i];
        if(vis[v]==0)
        {
            vis[v]=1;
            q.push(v);
        }
      }
    }
   for(int i=1;i<=n;i++)
   {
       if(vis[i]==0)
       {
           return 0;
       }
   }
   return 1;
}
void dfs(int u)
{
    if(has[u]==1&&vis[u]==0)
    {
        vis[u]=1;
        return ;
    }
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if(vis[v]==0&&has[v]==0)
        {
            vis[v]=1;
            dfs(v);
        }
        else if(vis[v]==0)
        {
            dfs(v);
        }
    }
    return ;
}
void init()
{
    for(int i=0;i<=n;i++)
    {
        has[i]=0;
        g[i].clear();
        vis[i]=0;
    }
    jud.clear();
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {

        scanf("%d%d%d",&n,&m,&k);
        init();
         int tx,ty;
         for(int i=0;i<k;i++)
           {
               scanf("%d",&tx);
               has[tx]=1;
           }

          for(int i=0;i<m;i++)
           {
               scanf("%d%d",&tx,&ty);
               g[tx].push_back(ty);
               g[ty].push_back(tx);
           }
          scanf("%d",&l);
         for(int i=0;i<l;i++)
         {
             scanf("%d",&tx);
             jud.push_back(tx);
         }
        if(l!=k||bfs()==0)
        {
            printf("No\n");continue;
        }
        memset(vis,0,sizeof(vis));
        bool marks=1;
        vis[jud[0]]=1;
        for(int i=0;i<l;i++)
        {
            if(vis[jud[i]]==0)
             {
                 marks=0;break;
             }
            dfs(jud[i]);
        }
        if(marks)
         printf("Yes\n");
        else
        printf("No\n");
    }
    return 0;
}
时间: 2024-10-12 19:54:59

zoj 3811 条件下判定某遍历序列的合法性/ 一遍 dfs的相关文章

HMM条件下的 前向算法 和 维特比解码

一.隐马尔科夫HMM假设: 有且只有3种天气:0晴天,1阴天,2雨天 各种天气间的隔天转化概率mp: mp[3][3] 晴天 阴天 雨天 晴天 0.33333 0.33333 0.33333 阴天 0.33333 0.33333 0.33333 雨天 0.33333 0.33333 0.33333 有2种活动:            0去公园,1不去公园 各种天气下进行各种活动的概率: w2a[3][2] 去公园 不去公园 晴天 0.75 0.25 阴天 0.4 0.6 雨天 0.25 0.75

根据二叉树的先序遍历序列和中序遍历序列求后序遍历序列

由先序遍历和中序遍历序列可唯一还原出二叉树,前提条件是所有节点的关键字无重复. 题目来源:http://hihocoder.com/problemset/problem/1049 代码: 1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 void post_order(string pre, string in) 7 { 8 size_t len = pre.length(); 9 if(l

二叉树的层次遍历(队列) and 二叉搜索树的后序遍历序列

(一)从上往下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印.[层次遍历] 从上到下打印二叉树的规律:每一次打印一个节点的时候,如果该节点有子节点,则把该节点的子节点放到一个队列的末尾.接下来到队列的头部取出最早进入队列的节点,重复前面的操作,直至队列中所有的节点都被打印出来为止. //二叉树的层次遍历#include<iostream>#include<queue>using namespace std; typedef int ElemType;typedef st

二叉树系列(二):已知中序遍历序列和后序遍历序列,求先序遍历序列

前面已经介绍过三种遍历方法的规则,为了大家看着方便,这里我们在重新介绍一遍: 1.先序遍历 (1)访问根结点: (2)先序遍历左子树: (3)先序遍历右子树.  2.中序遍历 (1)中序遍历左子树: (2)访问根结点: (3)中序遍历右子树. 3.后序遍历 (1)后序遍历左子树: (2)后序遍历右子树: (3)访问根结点. 知道了二叉树的三种遍历规则,只要有中序遍历序列和前后任一种遍历序列,我们就可以求出第三种遍历序列,今天我们研究的是已知中序和后序遍历序列,求先序遍历序列. 已知该二叉树的中序

二叉树求第三种遍历序列

// 树的结点的结构: struct TreeNode{ TreeNode* LChild; TreeNode* RChild; char data; }; 注意: 求第三种序列必须有中序序列,比如前中求后 以及 中后求前,不可以前后求中 第一种情况:有前序序列和中序序列,求后序序列 前序: GDAFEMHZ 中序:ADEFGHMZ 需求得后序:AEFDHZMG 思路:利用递归解决.有一个函数 TreeNode* find_post_order(char* inOrder, char* preO

二叉搜索树的后序遍历序列——24

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true,否则返回false.假设输入数组的任意两个数组都互不相同. 二叉搜索树的特点就是每个结点的左子树的值都比自身的值小,而右子树的值都比自身值要大.比如如上的二叉搜索树后序遍历的结果就是{5,7,6,9,11,10,8},但是题意并不是给出一棵二叉搜索树让判断数组是否为后序遍历序列,而是只有一组数据让判断是否为某个二叉搜索树的后序遍历结果,因此之能依据二叉搜索树后序遍历结果的特点来进行分析判断: 就拿上面的结果来说

zoj 3811 Untrusted Patrol(bfs或dfs)

Untrusted Patrol Time Limit: 3 Seconds      Memory Limit: 65536 KB Edward is a rich man. He owns a large factory for health drink production. As a matter of course, there is a large warehouse in the factory. To ensure the safety of drinks, Edward hir

判断一个数组是否是二叉搜索树的后序遍历序列 24

引言 ? ? 继续二叉树,这个题考的知识点是二叉树的后续遍历 ? ? 分析问题 ? ? 对于一个二叉树的后序遍历序列来说,最后一个数一定是根节点,然后前面的数中,从最开始到第一个大于根节点的数都是左子树中的数,而后面到倒数第二个数应该都是大于根节点的,是右子树,如果后面的数中有小于根节点的,那么说明这个序列不是二叉搜索树的后序遍历序列 ? ? 解决问题 ? ? 同样是用递归去做,首先要考虑Corner Case,如果array为空,那么返回false ? ? 然后找到根节点,根节点是array最

数据结构之 图论---基于邻接矩阵的广度优先搜索遍历(输出bfs遍历序列)

数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索(BFS)遍历,输出从某个顶点出发的遍历序列.(同一个结点的同层邻接点,节点编号小的优先遍历) 输入 输入第一行为整数n(0< n <100),表示数据的组数. 对于每组数据,第一行是三个整数k,m,t(0<k<100,0<m<(k-1)*k/2,0< t<k),