zoukankan      html  css  js  c++  java
  • spoj 2939 Query on a tree V 动态树分治

    题意:给一棵树,树上的节点黑白染色,初始时全黑。每次操作可以改变一个节点的颜色,或者查到某点最近的白点距离。


      1 #include<iostream>
    2 #include<cmath>
    3 #include<cstdio>
    4 #include<cstring>
    5 #include<algorithm>
    6 #include<queue>
    7 using namespace std;
    8 #define NMAX 100010
    9 struct node
    10 {
    11 int num;
    12 node *next;
    13 };
    14 struct tree
    15 {
    16 int num,d;
    17 bool w;
    18 tree *next;
    19 };
    20 priority_queue<int,vector<int>,greater<int> > Q[NMAX][2];
    21 priority_queue<int,vector<int>,greater<int> > del[NMAX][2];
    22 node *graph[NMAX];
    23 tree *belong[NMAX];
    24 tree memo_belong[50*NMAX];
    25 node memo[2*NMAX];
    26 bool color[NMAX];
    27 int size[NMAX],label;
    28 int n,m,top,root,ans;
    29 int sumsize,minsize;
    30 void add(int x,int y)
    31 {
    32 node *p=&memo[top++];
    33 p->num=y; p->next=graph[x]; graph[x]=p;
    34 p=&memo[top++];
    35 p->num=x; p->next=graph[y]; graph[y]=p;
    36 }
    37 void add_tree(int x,bool y,int d,int L)
    38 {
    39 tree *p=&memo_belong[top++];
    40 p->num=L; p->w=y; p->next=belong[x]; p->d=d; belong[x]=p;
    41 }
    42 void get_root(int i,int fa)
    43 {
    44 int big=-1;
    45 size[i]=1;
    46 for(node *p=graph[i];p;p=p->next)
    47 if(p->num!=fa)
    48 {
    49 get_root(p->num,i);
    50 size[i]+=size[p->num];
    51 if(size[p->num]>big) big=size[p->num];
    52 }
    53 if(sumsize-size[i]>big) big=sumsize-size[i];
    54 if(big<minsize) minsize=big,root=i;
    55 }
    56 void dfs2(int i,int d,bool w,int fa,int L)
    57 {
    58 add_tree(i,w,d,L);
    59 for(node *p=graph[i];p;p=p->next)
    60 if(p->num!=fa)
    61 dfs2(p->num,d+1,w,i,L);
    62 }
    63 void calc(int x)
    64 {
    65 int label,d,w,w_rev;
    66 for(tree *t=belong[x];t;t=t->next)
    67 {
    68 label=t->num; d=t->d; w=t->w;
    69 w_rev=!w;
    70 if(!Q[label][w_rev].empty())
    71 ans=min(ans,Q[label][w_rev].top()+t->d);
    72 }
    73 }
    74 void dfs(int i,int size_i)
    75 {
    76 if(size_i<=2) return ;
    77 sumsize=minsize=size_i;
    78 get_root(i,-1); i=root;
    79 get_root(i,-1);
    80 label++;
    81 int L=label;
    82 node *mid,*mid_next,*p,*left=graph[i];
    83 int sum=0;
    84 for(p=graph[i];p->next!=NULL;p=p->next)
    85 {
    86 sum+=size[p->num];
    87 if(sum>=(size_i-1)/2||p->next->next==NULL) break;
    88 }
    89 mid=p;
    90 mid_next=mid->next; mid->next=NULL;
    91 dfs2(i,0,0,-1,L);
    92 dfs(i,sum+1);
    93 mid->next=mid_next; graph[i]=mid_next;
    94 dfs2(i,0,1,-1,L);
    95 dfs(i,size_i-sum);
    96 }
    97 void update(int x)
    98 {
    99 tree *t;
    100 int label,d,w;
    101 for(t=belong[x];t;t=t->next)
    102 {
    103 label=t->num; d=t->d; w=t->w;
    104 if(color[x]==0)
    105 del[label][w].push(d);
    106 else Q[label][w].push(d);
    107 while(!del[label][w].empty()&&Q[label][w].top()==del[label][w].top())
    108 {
    109 Q[label][w].pop(); del[label][w].pop();
    110 }
    111 }
    112 }
    113
    114 int main()
    115 {
    116 int i,j;
    117 int x,y,z;
    118 scanf("%d",&n);
    119 label=top=0;
    120 memset(color,0,sizeof(color));
    121 memset(belong,0,sizeof(belong));
    122 memset(graph,0,sizeof(graph));
    123 for(i=1;i<n;i++)
    124 {
    125 scanf("%d%d",&x,&y);
    126 add(x,y);
    127 }
    128 top=0;
    129 size[1]=n;
    130 dfs(1,n);
    131 scanf("%d",&m);
    132 for(i=1;i<=m;i++)
    133 {
    134 scanf("%d",&y);
    135 if(y==0)
    136 {
    137 scanf("%d",&x);
    138 color[x]=!color[x];
    139 update(x);
    140 }
    141 else
    142 {
    143 scanf("%d",&x);
    144 if(color[x]==1) printf("0\n");
    145 else
    146 {
    147 ans=NMAX;
    148 calc(x);
    149 if(ans==NMAX) printf("-1\n");
    150 else printf("%d\n",ans);
    151 }
    152 }
    153 }
    154 return 0;
    155 }



  • 相关阅读:
    从 MVC 到微服务,技术演变的必经之路
    JBOSS最大连接数配置和jvm内存配置
    数据库原理及应用第7章课后习题答案
    如何实现超高并发的无锁缓存?
    手工清理win7系统C盘的技巧
    SVN版本回退
    在sql server数据库的一个表中如何查询共有多少字段
    软件测试的四个阶段
    sp_change_users_login 'Update_One', '用户名', '登录名';
    讲一讲java异常及自定义异常
  • 原文地址:https://www.cnblogs.com/myoi/p/2415649.html
Copyright © 2011-2022 走看看