Wannafly挑战赛10 C:小H和游戏

题目传送门

首先我们把无根树变成有根树
一个点的受损次数来自于:
1.父亲的父亲结点的贡献
2.父亲结点的贡献
3.兄弟结点的贡献
4.孩子结点的贡献

具体看代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn=750000+100;

vector<int>G[maxn];
int fa[maxn];//父亲结点 
int ans[maxn];//孩子结点对父亲结点和父亲的父亲结点的贡献
int a[maxn];//父亲结点和父亲的父亲结点对孩子结点的贡献
int res[maxn];//兄弟结点对兄弟结点的贡献,所以只要更新res[fa[x]],x的兄弟结点(包括自己)都可以得到贡献 

void dfs(int u,int f){

    fa[u]=f;
    int len=G[u].size();
    for(int i=0;i<len;i++){

        int v=G[u][i];
        if(v==f) continue;
        dfs(v,u);
    }
}

int main(){

    int n,q;
    scanf("%d%d",&n,&q);
    for(int i=1;i<n;i++){

        int u,v;
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    } 
    dfs(1,0);
    while(q--){

        int node;
        scanf("%d",&node);
        a[node]++;
        ans[fa[node]]++;ans[fa[fa[node]]]++;
        res[fa[node]]++;
        printf("%d\n",ans[node]+a[fa[node]]+a[fa[fa[node]]]+res[fa[node]]); //孩子结点的贡献+父亲结点的贡献+父亲的父亲结点的贡献+兄弟结点的贡献
    }
}

猜你喜欢

转载自blog.csdn.net/qq_37960603/article/details/81369434