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

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

    思路:同zjoi 2007 hide

      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,weight;
    12 node *next;
    13 };
    14 struct tree
    15 {
    16 int num,d;
    17 bool w;
    18 tree *next;
    19 };
    20 pair<int,int>child[NMAX*2];
    21 priority_queue<int> Q[NMAX][2];
    22 priority_queue<int> del[NMAX][2];
    23 node *graph[NMAX];
    24 tree *belong[NMAX];
    25 tree memo_belong[50*NMAX];
    26 node memo[2*NMAX];
    27 bool color[NMAX];
    28 int size[NMAX],label;
    29 int white_sum;
    30 int n,m,top,root,ans[NMAX*2];
    31 int sumsize,minsize;
    32 void add(int x,int y,int z)
    33 {
    34 node *p=&memo[top++];
    35 p->num=y; p->next=graph[x]; p->weight=z;graph[x]=p;
    36 p=&memo[top++];
    37 p->num=x; p->next=graph[y]; p->weight=z;graph[y]=p;
    38 }
    39 void add_tree(int x,bool y,int d,int L)
    40 {
    41 tree *p=&memo_belong[top++];
    42 p->num=L; p->w=y; p->next=belong[x]; p->d=d; belong[x]=p;
    43 }
    44 void get_root(int i,int fa)
    45 {
    46 int big=-1;
    47 size[i]=1;
    48 for(node *p=graph[i];p;p=p->next)
    49 if(p->num!=fa)
    50 {
    51 get_root(p->num,i);
    52 size[i]+=size[p->num];
    53 if(size[p->num]>big) big=size[p->num];
    54 }
    55 if(sumsize-size[i]>big) big=sumsize-size[i];
    56 if(big<minsize) minsize=big,root=i;
    57 }
    58 void dfs2(int i,int d,bool w,int fa,int L)
    59 {
    60 add_tree(i,w,d,L);
    61 Q[L][w].push(d);
    62 for(node *p=graph[i];p;p=p->next)
    63 if(p->num!=fa)
    64 dfs2(p->num,d+p->weight,w,i,L);
    65 }
    66 void calc(int L)
    67 {
    68 ans[L]=max(ans[child[L].first],ans[child[L].second]);
    69 if(!Q[L][0].empty()&&!Q[L][1].empty())
    70 ans[L]=max(ans[L],Q[L][0].top()+Q[L][1].top());
    71 }
    72 int dfs(int i,int size_i)
    73 {
    74 if(size_i<=2) return 0;
    75 sumsize=minsize=size_i;
    76 get_root(i,-1); i=root;
    77 get_root(i,-1);
    78 ++label;
    79 int L=label;
    80 node *mid,*mid_next,*p,*left=graph[i];
    81 int sum=0;
    82 for(p=graph[i];p->next!=NULL;p=p->next)
    83 {
    84 sum+=size[p->num];
    85 if(sum>=(size_i-1)/2||p->next->next==NULL) break;
    86 }
    87 mid=p;
    88 mid_next=mid->next; mid->next=NULL;
    89 dfs2(i,0,0,-1,L);
    90 child[L].first=dfs(i,sum+1);
    91 mid->next=mid_next; graph[i]=mid_next;
    92 dfs2(i,0,1,-1,L);
    93 child[L].second=dfs(i,size_i-sum);
    94 calc(L);
    95 return L;
    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]==1)
    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 calc(label);
    112 }
    113 }
    114
    115 int main()
    116 {
    117 ans[0]=-1;
    118 int i,j;
    119 char c[10];
    120 int x,y,z;
    121 scanf("%d",&n);
    122 label=top=0;
    123 memset(color,0,sizeof(color));
    124 memset(belong,0,sizeof(belong));
    125 memset(graph,0,sizeof(graph));
    126 for(i=1;i<n;i++)
    127 {
    128 scanf("%d%d%d",&x,&y,&z);
    129 add(x,y,z);
    130 }
    131 white_sum=n;
    132 top=0;
    133 size[1]=n;
    134 dfs(1,n);
    135 scanf("%d",&m);
    136 for(i=1;i<=m;i++)
    137 {
    138 scanf("%s",c);
    139 if(c[0]=='C')
    140 {
    141 scanf("%d",&x);
    142 if(color[x]==0) white_sum--;
    143 else white_sum++;
    144 color[x]=!color[x];
    145 update(x);
    146 }
    147 else
    148 {
    149 if(white_sum==0) printf("They have disappeared.\n");
    150 else if (white_sum==1)
    151 printf("0\n");
    152 else printf("%d\n",ans[1]);
    153 }
    154 }
    155 return 0;
    156 }
  • 相关阅读:
    linux源码方式安装Apache
    linux的chmod,chown命令详解
    2011年10月18日
    mysql检查查询及索引效率方法(explain)
    php中英文字符串的研究
    2011年10月20日
    PHP JSON中文乱码解决方法大全
    解决PHP下载文件名中文乱码
    php字符串学习笔记
    CSU_BMW正式组队纪念赛出题+部分解题报告
  • 原文地址:https://www.cnblogs.com/myoi/p/2415644.html
Copyright © 2011-2022 走看看