zoukankan      html  css  js  c++  java
  • HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

    题目链接:【http://acm.hdu.edu.cn/showproblem.php?pid=6203】

    题意  :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点。

    题解  :求每个点对的LCA,然后根据LCA的深度排序。从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1。

    #include<Bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5 + 5;
    int N, Q;
    int c[maxn], In[maxn], Out[maxn], cnt;
    struct Edge
    {
        int id, next;
        Edge(int id = 0, int next = 0): id(id), next(next) {}
    } E[maxn << 1]; //双向边
    int head[maxn], tot;
    void initEdge()
    {
        memset(c, 0, sizeof(c));
        cnt = 0;
        for(int i = 0; i <= N; i++) head[i] = -1;
        tot = 0;
    }
    void addEdge(int u, int v)
    {
        E[tot] = Edge(v, head[u]);
        head[u] = tot++;
    }
    int siz[maxn], top[maxn], dep[maxn], fa[maxn];
    int clk;//需要初始化
    void DFS1(int u, int p)
    {
        In[u] = ++cnt;
        dep[u] = dep[p] + 1;
        fa[u] = p, siz[u] = 1;
        for(int k = head[u]; k != -1; k = E[k].next)
        {
            int id = E[k].id;
            if(id == p) continue;
            DFS1(id, u);
            siz[u] += siz[id];
        }
        Out[u] = cnt;
    }
    void DFS2(int u, int p)
    {
        int son = -1;
        for(int k = head[u]; k != -1; k = E[k].next)//找重儿子
        {
            int id = E[k].id;
            if(id == p)continue;
            if(son == -1 || siz[id] > siz[son]) son = id;
        }
        if(son != -1)
        {
            top[son] = top[u];
            DFS2(son, u);
        }
        for(int k = head[u]; k != -1; k = E[k].next)
        {
            int id = E[k].id;
            if(id == p || id == son)continue;
            top[id] = id;
            DFS2(id, u);
        }
    }
    int LCA(int x, int y)
    {
        while(top[x] != top[y])
        {
            if(dep[top[x]] < dep[top[y]]) swap(x, y);
            x = fa[top[x]];
        }
        if(dep[x] > dep[y]) swap(x, y);
        return x;
    }
    
    
    
    
    struct node
    {
        int u, v, lca;
        bool operator < (const node &T) const
        {
            return dep[lca] > dep[T.lca];
        }
    } qry[50050];
    int low_Bit(int x)
    {
        return x & -x;
    }
    void update(int x, int val)
    {
        while(x <= N)
        {
            c[x] += val;
            x += low_Bit(x);
        }
    }
    int get_sum(int x)
    {
        int ret = 0;
        while(x > 0)
        {
            ret += c[x];
            x -= low_Bit(x);
        }
        return ret;
    }
    int main()
    {
        while(~scanf("%d", &N))
        {
            N++;
            initEdge();
            for(int i = 1; i <= N - 1; i++)
            {
                int u, v;
                scanf("%d %d", &u, &v);
                u++, v++;
                addEdge(u, v), addEdge(v, u);
            }
            DFS1(1, 0),top[1] = 1,DFS2(1, 0);
            scanf("%d", &Q);
            for(int i = 1; i <= Q; i++)
            {
                scanf("%d %d", &qry[i].u, &qry[i].v);
                qry[i].u++, qry[i].v++;
                qry[i].lca = LCA(qry[i].u, qry[i].v);
            }
            sort(qry + 1, qry + 1 + Q);
            int ans = 0;
            for(int i = 1; i <= Q; i++)
            {
                int u = qry[i].lca;
                int ret = get_sum(In[qry[i].u]) + get_sum(In[qry[i].v]);
                if(ret) continue;
                ans++;
                update(In[u], 1);
                update(Out[u] + 1, -1);
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    [SDOI2008]递归数列
    [SCOI2008]奖励关
    [SCOI2010]幸运数字
    [ZJOI2007]矩阵游戏
    [HAOI2006]旅行
    [ZJOI2008]泡泡堂
    [BZOJ1800][Ahoi2009]fly 飞行棋
    [POJ2288]Islands and Bridges
    [LUOGU] 3959 宝藏
    [BZOJ]1029: [JSOI2007]建筑抢修
  • 原文地址:https://www.cnblogs.com/pealicx/p/7562400.html
Copyright © 2011-2022 走看看