HDU 3974 Assign the task(dfs建树+线段树)

题目大意:公司里有一些员工及对应的上级,给出一些员工的关系,分配给某员工任务后,其和其所有下属都会进行这项任务。输入T表示分配新的任务,

输入C表示查询某员工的任务。本题的难度在于建树,一开始百思不得其解,后来看了lx大大的博客后才明白,用递归建立了各个员工之间的关系,Start[x]

表示x员工为Boss的起点,End[x]表示x员工为Boss的终点。之后对这样的整体线段进行赋值即可。

#include <stdio.h>
#include <algorithm>
#include <vector>
#include <string.h>
using namespace std;
#define lson rt<<1
#define rson rt<<1|1
#define N 50005
struct tree
{
    int l, r, task, iscover;
    int mid()
    {
        return (l+r)/2;
    }
}a[N<<2];
int vis[N], index, Start[N], End[N];
vector<int>G[N];
void dfs(int k)///模拟为boss树,记录各员工在树上的编号
{
    Start[k] = ++index;
    for(int i=0, len=G[k].size(); i<len; i++)
        dfs(G[k][i]);

    End[k] = index;
}
void build(int rt, int l, int r)
{
    a[rt].l = l;
    a[rt].r = r;
    a[rt].task = -1;
    a[rt].iscover = 0;
    if(l==r)return ;
    build(lson, l, a[rt].mid());
    build(rson, a[rt].mid()+1, r);
}
void Down(int rt)
{
    if(a[rt].l!=a[rt].r && a[rt].iscover)
    {
        a[lson].iscover = a[rson].iscover = 1;
        a[rt].iscover = 0;
        a[lson].task = a[rson].task = a[rt].task;
    }
}
void Update(int rt, int l, int r, int task)
{
    if(a[rt].l==l && a[rt].r==r)
    {
        a[rt].task = task;
        a[rt].iscover = 1;
        return ;
    }

    Down(rt);

    if(a[rt].mid()>=r)Update(lson, l, r, task);
    else if(a[rt].mid()<l)Update(rson, l, r, task);
    else
    {
        Update(lson, l, a[rt].mid(), task);
        Update(rson, a[rt].mid()+1, r, task);
    }
}
int Query(int rt, int k)
{
    if(a[rt].l==a[rt].r)
    {
        return a[rt].task;
    }

    Down(rt);

    if(a[rt].mid()>=k)return Query(lson, k);
    else return Query(rson, k);
}
int main()
{
    int T, icase = 1;
    scanf("%d", &T);
    while(T--)
    {
        int n, b, c;
        memset(vis, 0, sizeof(vis));
        scanf("%d", &n);
        for(int i=1; i<=n; i++)
            G[i].clear();
        for(int i=1; i<n; i++)
        {
            scanf("%d %d", &b, &c);
            G[c].push_back(b);
            vis[b] = 1;
        }
        index = 0;
        for(int i=1; i<=n; i++)
        {
            if(!vis[i])
            {
                dfs(i);///找到最高BOSS
                break;
            }
        }
        build(1, 1, n);
        int m, x, y;
        scanf("%d", &m);
        char order[10];
        printf("Case #%d:\n", icase++);
        while(m--)
        {
            scanf("%s", order);
            if(order[0]=='T')
            {
                scanf("%d %d", &x, &y);
                Update(1, Start[x], End[x], y);
            }
            else
            {
                scanf("%d", &x);
                printf("%d\n", Query(1, Start[x]));
            }
        }
    }
    return 0;
}

 

posted on 2016-07-13 15:43  刘威O_0  阅读(198)  评论(0编辑  收藏  举报

导航