BZOJ 2815: [ZJOI2012]灾难

呃,题面没了,大概就是给出一些生物之间的捕食关系,求灭绝树每个点的灾难值。

 

拓扑排序之后倒着加入点,动态维护fa[][]数组,倍增法求LCA,当然大佬愿意写动态树也是极好的……

 

  1 #include <cstdio>
  2 
  3 inline int nextChar(void) {
  4     const int siz = 1024;
  5     
  6     static char buf[siz];
  7     static char *hd = buf + siz;
  8     static char *tl = buf + siz;
  9     
 10     if (hd == tl)
 11         fread(hd = buf, 1, siz, stdin);
 12         
 13     return *hd++;
 14 }
 15  
 16 inline int nextInt(void) {
 17     register int ret = 0;
 18     register int neg = false;
 19     register int bit = nextChar();
 20     
 21     for (; bit < 48; bit = nextChar())
 22         if (bit == '-')neg ^= true;
 23         
 24     for (; bit > 47; bit = nextChar())
 25         ret = ret * 10 + bit - 48;
 26         
 27     return neg ? -ret : ret;
 28 }
 29 
 30 const int siz = 800005;
 31 
 32 int n;
 33 
 34 int cnt[siz];
 35 
 36 int tot1;
 37 int hd1[siz];
 38 int to1[siz];
 39 int nt1[siz];
 40 
 41 inline void add1(int u, int v)
 42 {
 43     nt1[tot1] = hd1[u]; to1[tot1] = v; hd1[u] = tot1++;
 44 }
 45 
 46 int tot2;
 47 int hd2[siz];
 48 int to2[siz];
 49 int nt2[siz];
 50 
 51 inline void add2(int u, int v)
 52 {
 53     nt2[tot2] = hd2[u]; to2[tot2] = v; hd2[u] = tot2++;    
 54 }
 55 
 56 int dep[siz], fa[siz][25];
 57 
 58 inline int lca(int a, int b)
 59 {    
 60     if (a == -1)
 61         return b;
 62         
 63     if (dep[a] < dep[b])
 64         a ^= b ^= a ^= b;
 65     
 66     for (int i = 24; i >= 0; --i)
 67         if (dep[fa[a][i]] >= dep[b])
 68             a = fa[a][i];
 69     
 70     if (a == b)
 71         return a;
 72     
 73     for (int i = 24; i >= 0; --i)
 74         if (fa[a][i] != fa[b][i])
 75             a = fa[a][i],
 76             b = fa[b][i];
 77             
 78     return fa[a][0];
 79 }
 80 
 81 int que[siz], head, tail;
 82 
 83 int sz[siz];
 84 
 85 void dfs(int u)
 86 {
 87     for (int i = hd2[u]; ~i; i = nt2[i])
 88         dfs(to2[i]), sz[u] += sz[to2[i]];
 89         
 90     ++sz[u];
 91 }
 92 
 93 signed main(void)
 94 {
 95     n = nextInt();
 96     
 97     for (int i = 0; i <= n; ++i)
 98         hd1[i] = hd2[i] = -1;
 99     
100     for (int i = 1, t; i <= n; ++i)
101         while (t = nextInt(), t)
102             add1(i, t), ++cnt[t];
103             
104     for (int i = 1; i <= n; ++i)
105         if (!cnt[i])que[tail++] = i;
106             
107     while (head != tail)
108     {
109         int u = que[head++], v;
110         
111         for (int i = hd1[u]; ~i; i = nt1[i])
112             if (!(--cnt[v = to1[i]]))que[tail++] = v;
113     }
114     
115     for (int i = tail - 1; i >= 0; --i)
116     {
117         int u = que[i], v = -1;
118         
119         for (int j = hd1[u]; ~j; j = nt1[j])
120             v = lca(v, to1[j]);
121             
122         if (v == -1)v = 0;
123         
124         add2(v, u);
125         
126         fa[u][0] = v;
127         
128         dep[u] = dep[v] + 1;
129         
130         for (int j = 1; j < 25; ++j)
131             fa[u][j] = fa[fa[u][j - 1]][j - 1];
132     }
133     
134     dfs(0);
135     
136     for (int i = 1; i <= n; ++i)
137         printf("%d\n", sz[i] - 1);
138 }

 

@Author: YouSiki

 

posted @ 2017-01-05 21:35  YouSiki  阅读(216)  评论(0编辑  收藏  举报