CodeForces 580C 树+dfs搜索

Description

Kefa decided to celebrate his first big salary by going to the restaurant.

He lives by an unusual park. The park is a rooted tree consisting of n vertices with the root at vertex 1. Vertex 1 also contains Kefa’s house. Unfortunaely for our hero, the park also contains cats. Kefa has already found out what are the vertices with cats in them.

The leaf vertices of the park contain restaurants. Kefa wants to choose a restaurant where he will go, but unfortunately he is very afraid of cats, so there is no way he will go to the restaurant if the path from the restaurant to his house contains more than mconsecutive vertices with cats.

Your task is to help Kefa count the number of restaurants where he can go.

Input

The first line contains two integers, n and m (2?≤?n?≤?105, 1?≤?m?≤?n) — the number of vertices of the tree and the maximum number of consecutive vertices with cats that is still ok for Kefa.

The second line contains n integers a1,?a2,?…,?an, where each ai either equals to 0 (then vertex i has no cat), or equals to 1 (then vertex i has a cat).

Next n?-?1 lines contains the edges of the tree in the format “xiyi” (without the quotes) (1?≤?xi,?yi?≤?n, xi?≠?yi), where xi and yi are the vertices of the tree, connected by an edge.

It is guaranteed that the given set of edges specifies a tree.

Output

A single integer — the number of distinct leaves of a tree the path to which from Kefa’s home contains at most m consecutive vertices with cats.

Sample Input

Input

4 1

1 1 0 0

1 2

1 3

1 4

Output

2

Input

7 1

1 0 1 1 0 0 0

1 2

1 3

2 4

2 5

3 6

3 7

Output

2

Hint

Let us remind you that a tree is a connected graph on n vertices and n?-?1 edge. A rooted tree is a tree with a special vertex called root. In a rooted tree among any two vertices connected by an edge, one vertex is a parent (the one closer to the root), and the other one is a child. A vertex is called a leaf, if it has no children.

Note to the first sample test: The vertices containing cats are marked red. The restaurants are at vertices 2, 3, 4. Kefa can’t go only to the restaurant located at vertex 2.

Note to the second sample test: The restaurants are located at vertices 4, 5, 6, 7. Kefa can’t go to restaurants 6, 7.

题意解析

  • 建成一颗树从根出发到叶节点为一条路径
  • 路上不能有大于m个“连续consecutive”有猫的节点
  • 数有几条符合的路径

第一次未ac代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>

using namespace std;

int n,m;
bool cat[100005];
bool visited[100005];
vector<int> tree[100005];
int road=0;

void dfs(int v,int mao){//到当前结点有连续几只猫
    if(mao>m)return;
    int l=tree[v].size();
    if(!l){//leave

        road++;
        return ;
    }
    int w;
    for(int i=0;i<l;i++){
        w=tree[v][i];
        if(cat[w]){
            dfs(w,mao+1);
        }
        else{
            dfs(w,0);
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    int d;
    for(int i=1;i<=n;i++){
        scanf("%d",&d);
        cat[i]=d;
    }
    int u,v;
    for(int i=1;i<n;i++){
        scanf("%d%d",&u,&v);
        tree[u].push_back(v);
    }
    if(cat[1]) dfs(1,1);
    else
    dfs(1,0);
    printf("%d\n",road);
    return 0;
}

错误原因

  • 建树时默认输入数据为根到节点,建立单向图

    ## 修改 ##

  • 建立双向图
  • 新bug:单向图时叶节点的判断采用无出边即为叶节点

    -{典型修改之后不记得跟之前做题的思路哪里有出路,又输出调试找了好久定位bug}

  • 修改:无可走的连通节点即为叶节点
  • 列表内容

最终修改ac代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>

using namespace std;

int n,m;
bool cat[100005];
bool visited[100005];
vector<int> tree[100005];
int road=0;

void dfs(int v,int mao){//到当前结点有连续几只猫
     visited[v]=1;
   // cout<<"dfs"<<endl;
    if(mao>m)return;
    int l=tree[v].size();
    /*if(!l){//leave

    }
    */
    bool flag=true;
    int w;
    for(int i=0;i<l;i++){
        w=tree[v][i];
        if(!visited[w])
        {   //cout<<"w: "<<w<<endl;
             flag=false;
            if(cat[w]){
                dfs(w,mao+1);
            }
            else{
                dfs(w,0);
            }
            visited[w]=1;
        }
    }
    if(flag){//leave
    //  cout<<"resturant:"<<v<<endl;
        road++;
        return ;
    }
}
int main(){
    scanf("%d%d",&n,&m);
    int d;
    for(int i=1;i<=n;i++){
        scanf("%d",&d);
        cat[i]=d;
    }
    int u,v;
    for(int i=1;i<n;i++){
        scanf("%d%d",&u,&v);
        tree[u].push_back(v);
        tree[v].push_back(u);
    }

    if(cat[1]) dfs(1,1);
    else
    dfs(1,0);
    printf("%d\n",road);
    return 0;
}
时间: 2024-10-16 08:42:06

CodeForces 580C 树+dfs搜索的相关文章

codeforces 570 D. Tree Requests 树状数组+dfs搜索序

链接:http://codeforces.com/problemset/problem/570/D D. Tree Requests time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Roman planted a tree consisting of n vertices. Each vertex contains a low

Codeforces 384E 线段树+dfs序

题目链接:点击打开链接 题意: 给定n个点,m个询问的无向树(1为根) 下面n个数表示每个点的权值 下面n-1行给出树 操作1:x点权值+v, x的第 i & 1 的儿子-v, 第 !(i&1) 的儿子+v 操作2:询问x点权值 dfs把树转成序列 根据深度把点分成2组 分别用线段树维护.. 然后Y一下 #include<stdio.h> #include<string.h> #include<iostream> #include<algorith

hdu 1298 T9(字典树+DFS)

题目连接:hdu 1298 T9 题目大意:模拟手机打字的猜想功能,根据概率,每按一个按键,输出可能性最高的串.先给定N个单词,以及频率, 然后是Q次询问,每次询问给定一个按按键的顺序,以1为终止. 解题思路:对单词表建立字典树,每个节点有一个经过的频率,这个频率是根据所有经过该节点的单词频率总和.然后 DFS搜索一遍,将答案保存在ans中. #include <cstdio> #include <cstring> #include <algorithm> using

[ZOJ 1011] NTA (dfs搜索)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1011 题目大意:在一棵树上,给你起始状态,问你能否到达终止状态. 给了树的前序遍历序. 直接dfs搜索. 1 #include <cstdio> 2 #include <cstdlib> 3 #include <string> 4 #include <iostream> 5 #include <cstring>

Luogu_P2536 [AHOI2005]病毒检测 trie树+dfs

Luogu_P2536 [AHOI2005]病毒检测 ### trie树+dfs 题目链接 这两个符号比较有意思 可以把所有的串都先建到trie树上 然后用病毒的模式串在上面搜索 处理这两个符号就可以通过搜索次序解决 主要可以看代码 问的是非病毒,WA了 一个符号可以不取,又WA了 代码如下: #include<bits/stdc++.h> using namespace std; string bd,w[1010]; int ans,n,trie[250010][10],tot=1,ed[2

hdu1372 dfs搜索之国际象棋的马

原题地址 题意 一个8x8的国际象棋棋盘,你有一个棋子"马".算出棋子"马"从某一格到另一格子的最少步数. 与普通dfs不同的是,你能走的路线不是上下左右,四个方向.而是由"日" 字组成的8个方向.虽然是国际象棋的马,但是其实和中国象棋的马走法还是一样的. 代码 #include<iostream> #include<cstdio> #include<cstring> using namespace std;

HDU 5692 线段树+dfs序

Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1779    Accepted Submission(s): 427 Problem Description 百度科技园内有n 个零食机,零食机之间通过n−1 条路相互连通.每个零食机都有一个值v ,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充,零食机的价值v

Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序

题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s   内存限制:512.0MB 总提交次数:196   AC次数:65   平均分:58.62 将本题分享到: 查看未格式化的试题   提交   试题讨论 试题来源 2013中国国家集训队第二次作业 问题描述 给定一棵N个节点的树,每个点有一个权值,有M个询问(a,b,c)若a 为1,回答b到c路径上的最小权值,若a为2,回答b到c路径上的最大权值,若a为3,回答b到c路径上的所有权值的

Trie树 + DFS - CSU 1457 Boggle

Boggle Problem's Link: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1457 Mean: 给定n个串,有m个询问. 每个询问给你一个4*4的字符矩阵,你可以在这个字符矩阵中任意字符出发,向四个方向走(已走过的不可重复走),走出一个字符串. 如果n个串中有对应的串和走出的字符串相同,那么需要求出: 1.不同长度的串给了不同的权值,n个串中出现的串的总权值是多少? 2.从出现的字符串中找一个最长的出来,如果有多个,找一个字典