小H和遊戲(樹形結構)

在這裏插入圖片描述
解題思路:
最直接的想法是,每次轟炸一個點時,將距離2以內的點的轟炸次數都加1,但是這可能會產生一個問題,很容易被卡,如果只有一個父親節點,n-1個兒子節點,那麼複雜度爲O(n^2)
所以應該採取另外一個方法,即每次轟炸將貢獻傳遞給父親和爺爺還有自身,這樣每次就降低了複雜度,每次次數詢問時,只需查詢父親、爺爺、自身的貢獻次數就行
即一個點的兄弟受到轟炸它也受到轟炸,這記錄在父親節點,一個點的爺爺受到轟炸它也受到轟炸,這記錄在爺爺節點,一個點的兒子和孫子受到轟炸它也受到轟炸,這記錄在節點本身。
代碼:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=750000;
int f[maxn+10];
int sum[maxn+10][3];
vector<int> e[maxn+10];
int n,t;
void dfs(int u,int fa)
{
    f[u]=fa;
    for(auto c:e[u])
    {
        if(c==fa) continue;
        dfs(c,u);
    }
}
int main()
{
    cin>>n>>t;
    for(int i=0;i<n-1;++i)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs(1,0);
    while(t--)
    {
        int pos;
        scanf("%d",&pos);
        sum[pos][2]++;
        sum[pos][1]++;
        sum[f[pos]][1]++;
        sum[f[pos]][0]++;
        sum[f[f[pos]]][0]++;
        printf("%d\n",sum[pos][0]+sum[f[pos]][1]+sum[f[f[pos]]][2]);
       // cout<<sum[pos][0]+sum[f[pos]][1]+sum[f[f[pos]]][2]<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章