zstu3999——邻接表

Description

多组测试数据  给你一棵树,n个点(n<=10000),树的根为root(root<=n),然后有Q个询问,每个询问输入一个数x,求以x为根的子树有多少个点?

Input

每组的第一行是一个整数n和一个整数root  接下来n-1行是这棵树的n-1条边,每行两个数a b,代表a点和b点之间有一条边  然后是一个整数Q,代表询问的数量  最后Q行每行是一个整数(Q<=n)

Output

对于每个询问,输出以当前点为根的子树的节点总数

Sample Input

3 1

1 2

1 3

1

1

Sample Output

3

HINT

 

Source

Submit  Status  Web Board
 大意:用vector来保存每一个节点的儿子节点,dfs大法好
学习了几个vector的处理函数
vector.begin()开始的点 ,vector.end()最后的点,vector.clear()清空,这个很重要~~
还有迭代器相当于一个指针 vector :: iterator i定义i为vector的一个指针
#include<cstdio>

#include<cstring>

#include<algorithm>

#include<vector>

using namespace std;

const int maxn = 10100;

int mark[maxn],cot[maxn];

vector<int> G[10100];

int dfs(int root)

{

    mark[root] = 1;

    if(G[root].size() == 0){

        cot[root] = 1;

        return 1;

    }

    vector<int>:: iterator endd = G[root].end();

    for(vector<int>:: iterator i = G[root].begin(); i!= endd; i++){

        if(mark[*i]) continue;

        cot[root] += dfs(*i);

    }

    cot[root]++;

    return cot[root];

}

int main()

{

    int n,m,q,x;

    int a,b;

    while(~scanf("%d%d",&n,&m)){

        memset(mark,0,sizeof(mark));

        memset(cot,0,sizeof(cot));

        for(int i = 1; i < n ;i++){

            scanf("%d%d",&a,&b);

            G[a].push_back(b);

            G[b].push_back(a);

        }

        dfs(m);

      scanf("%d",&q);

      for(int i = 1; i <= q; i++){

          scanf("%d",&x);

          printf("%d\n",cot[x]);

      }

      for(int i = 1; i <= n;i++)

          G[i].clear();

    }

    return 0;

}

 

你可能感兴趣的:(表)