树的分治

来源:互联网 发布:三菱伺服驱动器编程 编辑:程序博客网 时间:2024/04/30 05:15
我人生中第一个树的分治终于写好了。
看以前的论文(QZC神牛的论文),感觉不是很高深,但是准备写了却发现各种bug依次而来。总想把常数写小一点,但是每次发现好些点的都是常数大的。算了,就好些点算了,感觉也不错,只写了80+行,写的也很漂亮,自己挺喜欢的。这估计是我dfs写的最多的一个程序了。

最后,还是献上我的代码:

#include <stdio.h>#include <memory.h>#define maxn 100500const int oo = 0x3F3F3F3F;typedef struct {int t, n; } etype;int size[maxn];int depth[maxn];int count[maxn];int edge[maxn];int tms[maxn];int chk[maxn];etype g[maxn << 1];int etop = 0, stdtms = 0, total = 0;int censize, centroid;void dfs_init (int u, int f, int d){  int e, p;  size[u] = 1, depth[u] = d, tms[d] != stdtms ? tms[d] = stdtms, count[d] = 1 : (++count[d]);  for (e = edge[u], ++d; e; e = g[e].n)    if (!chk[p = g[e].t] && p != f)      dfs_init (p, u, d), size[u] += size[p];}void dfs_find (int u, int f){  int e, minsize = total - size[u], p;  for (e = edge[u]; e; e = g[e].n)    if (!chk[p = g[e].t] && p != f)      dfs_find (p, u), minsize < size[p] ? minsize = size[p] : 0;  if (minsize < censize)    censize = minsize, centroid = u;}int calc (int u, int d){  int ans = 0, i;  ++stdtms;  dfs_init (u, 0, 0);  for (i = 0; i << 1 < d && tms[i] == stdtms; ++i)    if (tms[d - i] == stdtms)      ans += count[d - i] * count[i];  if (i << 1 == d && tms[i] == stdtms)    ans += count[i] * (count[i] - 1) >> 1;  return ans;}int dfs_div (int u, int d){  int e, p, ans = 0;  ans += calc (u, d), chk[u] = 1; for (e = edge[u]; e; e = g[e].n)   if (!chk[g[e].t])     ans -= calc (g[e].t, d - 2);  for (e = edge[u]; e; e = g[e].n)    if (!chk[p = g[e].t])      total = size[p], censize = oo, dfs_find (p, u), ans += dfs_div (centroid, d);  return ans;}void adde (int s, int t){  g[++etop] = (etype){t, edge[s]}, edge[s] = etop;  g[++etop] = (etype){s, edge[t]}, edge[t] = etop;}int main(){  FILE *fin  = fopen ("three.in" , "r");  FILE *fout = fopen ("three.out", "w");  int n, d, i, s, t;  fscanf (fin, "%d%d", &n, &d);  for (i = 1; i < n; ++i)    fscanf (fin, "%d%d", &s, &t), adde (s, t);  fprintf (fout, "%d", dfs_div (1, d));  fclose (fin);  fclose (fout);  return 0;}


原创粉丝点击