hdu6162 Ch’s gift(LCA)

来源:互联网 发布:bat 算法工程师 编辑:程序博客网 时间:2024/05/16 18:37

题意:

给你一棵树,每个节点有一个价值,要执行m次询问,每次询问输入四个数,s,t,a,b,求解s到t的最短路,并把路径上节点的价值在[a,b]之间的价值求和输出。

思路:

对每组询问,求LCA(开始询问前先以1为根节点dfs一遍,确定每个节点的高度,开始每组询问时,根据高度差迭代求lca,详情看代码),并在求解过程判断价值符不符合要求。

代码:

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 1e5+7;ll ans[maxn],arr[maxn];int height[maxn],fa[maxn];vector<int> e[maxn];int n,m;void dfs(int u,int f,int h){    height[u] = h;    fa[u] = f;    int len = e[u].size();    for(int i = 0;i<len;i++)    {        int v= e[u][i];        if(v!=f)        {            dfs(v,u,h+1);        }    }}ll solve(int s,int t,int a,int b){    ll res = 0;    if(t==1)    {        while(s!=0)        {            if(arr[s]>=a&&arr[s]<=b)                res+=arr[s];            s = fa[s];        }        return res;    }    if(s==1)    {        while(t!=0)        {            if(arr[t]>=a&&arr[t]<=b)                res+=arr[t];            t = fa[t];        }        return res;    }    while(1)    {        if(height[t]==height[s])        {            if(t==s)            {                if(arr[s]>=a&&arr[s]<=b)                    res+=arr[s];                return res;            }            else            {                if(arr[s]>=a&&arr[s]<=b)                    res+=arr[s];                s = fa[s];            }        }        else if(height[s]>height[t])        {            if(arr[s]>=a&&arr[s]<=b)                    res+=arr[s];                s = fa[s];        }        else        {            if(arr[t]>=a&&arr[t]<=b)                res+=arr[t];            t = fa[t];        }    }    return res;}int main(){    while(~scanf("%d%d",&n,&m))    {        for(int i = 1;i<=n;i++)            e[i].clear();        for(int i = 1;i<=n;i++)            scanf("%lld",arr+i);        for(int i = 0;i<n-1;i++)        {            int u,v;            scanf("%d%d",&u,&v);            e[u].push_back(v);            e[v].push_back(u);        }        dfs(1,0,1);        for(int i = 0;i<m;i++)        {            int s,t,a,b;            scanf("%d%d%d%d",&s,&t,&a,&b);            ans[i] = solve(s,t,a,b);        }        for(int i= 0;i<m;i++)        {            if(i!=m-1)                printf("%lld ",ans[i]);            else                printf("%lld\n",ans[i]);        }    }    return 0;}