zoukankan      html  css  js  c++  java
  • HDU 6203 ping ping ping(dfs序+LCA+树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=6203

    题意:

    n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V 无法连通。问无法通行的点最少有多少个。

    思路:

    贪心思维,破坏两个点的LCA是最佳的。那么怎么判断现在在(u,v)之间的路径上有没有被破坏的点呢,如果没有的话那么此时就要破坏这个lca点。一开始我们要把询问按照u和v的lca深度从大到小排序,如果某个点需要被破坏,那么它的所有子节点都可以不再需要破坏别的点了(因为它的子节点到别的子节点肯定是要经过该点的,要注意这个前提是lca是排好序的,自己脑补一下~)。

    所以,用dfs序来维护子节点是最好的,记录in和out两个数组。然后用树状数组来维护。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<sstream>
      6 #include<vector>
      7 #include<stack>
      8 #include<queue>
      9 #include<cmath>
     10 #include<map>
     11 #include<set>
     12 using namespace std;
     13 typedef long long ll;
     14 typedef pair<int,ll> pll;
     15 const int INF = 0x3f3f3f3f;
     16 const int maxn = 1e4+5;
     17 
     18 int n;
     19 int Log;
     20 int dfs_clock;
     21 int in[maxn],out[maxn];
     22 int deep[maxn];
     23 int p[maxn][100];
     24 int c[2*maxn];
     25 vector<int> G[maxn];
     26 
     27 struct node
     28 {
     29     int u,v,lca;
     30 }query[50005];
     31 
     32 void dfs(int u, int fa, int d)
     33 {
     34     in[u]=++dfs_clock;
     35     deep[u]=d;
     36     p[u][0]=fa;
     37     for(int i=0;i<G[u].size();i++)
     38     {
     39         int v=G[u][i];
     40         if(v==fa)  continue;
     41         dfs(v,u,d+1);
     42     }
     43     out[u]=++dfs_clock;
     44 }
     45 
     46 
     47 bool cmp(node a, node b)
     48 {
     49     return deep[a.lca]>deep[b.lca];
     50 }
     51 
     52 
     53 void init()
     54 {
     55     for(int j=1;j<=Log;j++)
     56         for(int i=1;i<=n;i++)
     57              p[i][j]=p[p[i][j-1]][j-1];
     58 }
     59 
     60 
     61 int LCA(int x, int y)
     62 {
     63     if(x==y)  return x;
     64     if(deep[x]<deep[y])  swap(x,y);
     65     for(int i=Log;i>=0;i--)
     66     {
     67         if(deep[p[x][i]]>=deep[y])
     68             x=p[x][i];
     69     }
     70     if(x==y)  return x;
     71     for(int i=Log;i>=0;i--)
     72     {
     73         if(p[x][i]!=p[y][i])
     74         {
     75             x=p[x][i];y=p[y][i];
     76         }
     77     }
     78     return p[x][0];
     79 }
     80 
     81 int lowbit(int x)
     82 {
     83     return x&(-x);
     84 }
     85 
     86 int sum(int x)
     87 {
     88     int ret = 0;
     89     while(x>0)
     90     {
     91         ret+=c[x];
     92         x-=lowbit(x);
     93     }
     94     return ret;
     95 }
     96 
     97 void add(int x, int d)
     98 {
     99     while(x<=2*n)
    100     {
    101         c[x]+=d;
    102         x+=lowbit(x);
    103     }
    104 }
    105 
    106 int main()
    107 {
    108     //freopen("in.txt","r",stdin);
    109     while(~scanf("%d",&n))
    110     {
    111         dfs_clock=0;
    112         memset(c,0,sizeof(c));
    113         memset(p,0,sizeof(p));
    114         for(int i=0;i<=n+1;i++)   G[i].clear();
    115         for(int i=0;i<n;i++)
    116         {
    117             int u,v;
    118             scanf("%d%d",&u,&v);
    119             u++;v++;
    120             G[u].push_back(v);
    121             G[v].push_back(u);
    122         }
    123         n++;
    124         for(Log=0;(1<<Log)<=n;Log++);
    125         Log--;
    126 
    127         dfs(1,1,1);
    128         init();
    129         int q;
    130         scanf("%d",&q);
    131         for(int i=1;i<=q;i++)
    132         {
    133             scanf("%d%d",&query[i].u,&query[i].v);
    134             query[i].u++;query[i].v++;
    135             query[i].lca=LCA(query[i].u,query[i].v);
    136         }
    137         sort(query+1,query+q+1,cmp);
    138         int ans=0;
    139         for(int i=1;i<=q;i++)
    140         {
    141             int u=query[i].u,v=query[i].v,lca=query[i].lca;
    142             int tmp1=sum(in[u]),tmp2=sum(in[v]);
    143             if(sum(in[u])+sum(in[v]))  continue;
    144             else
    145             {
    146                 ans++;
    147                 add(in[lca],1);
    148                 add(out[lca],-1);
    149             }
    150         }
    151         printf("%d
    ",ans);
    152     }
    153     return 0;
    154 }
  • 相关阅读:
    单元测试之道读书笔记(七)
    单元测试之道读书笔记(六)
    单元测试之道读书笔记(五)
    单元测试之道读书笔记(三)
    技术网站推荐
    CentOS7部署Haproxy 1.7.2
    Centos7.0配置MySQL主从服务器
    Centos7.0安装mysql5.6
    centos7配置Java环境
    Centos6.5 DNS配置
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7554692.html
Copyright © 2011-2022 走看看