wannafly 挑战赛10 小H和游戏

题解:

先利用dfs找出各个节点之间的关系。然后利用一个sum[i][j] 数组  sum[i][0] 表示i这个节点收到影响的次数 sum[i][1]表示i这个节点的儿子们收到影响的次数 sum[i][2]表示i的孙子们受到影响的次数,那么我们

可以用sum[f[f[x]]][2]+sum[f[x]][1]+sum[x][0] 表示x这个点被炸的次数,当要轰炸x的时候,
        sum[f[f[x]]][0]++; // grafa
        sum[f[x]][0]++;// fa
        sum[f[x]][1]++; // x以及x的兄弟们
        sum[x][1]++;// son
        sum[x][2]++; // 
便可以覆盖所有的情况

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int n,q;
int f[750001];
int sum[750001][4];
vector<int> edge[750001];

void dfs(int pos,int fa)
{
    int len=edge[pos].size();//
    f[pos]=fa;
    for(int i=0;i<len;i++)
    {
        int next = edge[pos][i];
        if(next!=fa)
        {
            dfs(next,pos);
        }
    }
}


int main()
{
    cin>>n>>q;
    for(int i=0;i<n;i++) edge[i].clear();
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        edge[x].push_back(y);
        edge[y].push_back(x);
    }
    dfs(1,1);
    memset(sum,0,sizeof(sum));
    f[1]=0;
    f[0]=0;
    while(q--)
    {
        int x;
        cin>>x;
        sum[f[f[x]]][0]++;
        sum[f[x]][0]++;
        sum[f[x]][1]++; // sum[x][0]++ 这么写是错的是因为漏掉了他的兄弟们。。。
        sum[x][1]++;
        sum[x][2]++;
        cout<<sum[f[f[x]]][2]+sum[f[x]][1]+sum[x][0]<<endl;
    }
    return 0;
}

 

posted @ 2018-02-26 19:47  猪突猛进!!!  阅读(162)  评论(0编辑  收藏  举报