zoukankan      html  css  js  c++  java
  • 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:
    ", 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
    ", Query(1, Start[x]));
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    如何取消隐藏工作簿,使工作簿可见
    Android小知识总结
    Android内存泄露总结
    Ubuntu 升级VisualBox后无法启动 Kernel driver not installed (rc=-1908)
    Eclipse颜色主题插件:Eclipse Color Theme
    使用Json的注意事项
    android中正确导入第三方jar包
    设计模式--单例模式学习
    比较好的学习网址总结
    二叉树学习总结(Java实现)
  • 原文地址:https://www.cnblogs.com/zznulw/p/5667141.html
Copyright © 2011-2022 走看看