zoukankan      html  css  js  c++  java
  • 再会 树剖

     终于AC:([SPOJ-QTREE],VJudge

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 using namespace std;
      5 #define maxn 10010
      6 struct Edge{
      7     int u,v,w,next;
      8 }e[maxn*2];
      9 struct Node{
     10     int l,r,val;
     11     Node *lc,*rc;
     12 }*root=NULL;
     13 int t,n,m,head[maxn*2],js,p,siz[maxn];
     14 int fa[maxn],son[maxn],dep[maxn],top[maxn],pos[maxn];
     15 //fa=父亲 son=重孩子 top=所在重链的链顶
     16 //pos在线段树中的位置 siz以v为顶的子树的孩子数
     17 void memsett(){
     18     js=0,p=0;
     19     memset(head,0,sizeof(head));
     20     memset(e,0,sizeof(e));
     21     memset(son,0,sizeof(son));
     22 }
     23 void Add_Edge(int u,int v,int w){
     24     e[++js].u=u;e[js].v=v;e[js].w=w;
     25     e[js].next=head[u];head[u]=js;
     26 }
     27 void DFS(int now,int f,int deepth){
     28     fa[now]=f;dep[now]=deepth;siz[now]=1;
     29     for(int i=head[now];i;i=e[i].next){
     30         int v=e[i].v;
     31         if(v!=f){
     32             DFS(v,now,deepth+1);siz[now]+=siz[v];
     33             if(!son[now]||siz[son[now]]<siz[v])
     34                 son[now]=v;
     35         }
     36     }
     37 }
     38 void GetTop(int u,int tp){
     39     top[u]=tp;pos[u]=++p;
     40     if(!son[u])return ;
     41     GetTop(son[u],tp);
     42     for(int i=head[u];i;i=e[i].next){
     43         int v=e[i].v;
     44         if(v!=son[u]&&v!=fa[u]) GetTop(v,v);
     45     }
     46 }
     47 void Build(Node * &pt,int l,int r){
     48     pt=new(Node);pt->l=l;pt->r=r;pt->val=0;
     49     if(l==r){
     50         pt->lc=pt->rc=NULL;return;
     51     }
     52     int mid=(l+r)/2;
     53     Build(pt->lc,l,mid);Build(pt->rc,mid+1,r);
     54 }
     55 void UpDate(Node *p,int ps,int val){
     56     if(p->l==p->r){ p->val=val;return; }
     57     int mid=(p->l+-p->r)/2;
     58     if(ps<=mid)UpDate(p->lc,ps,val);
     59     else UpDate(p->rc,ps,val);
     60     p->val=max(p->lc->val,p->rc->val);
     61 }
     62 int query(Node * p,int l,int r){
     63     if(l<=p->l&&p->r<=r)return p->val;
     64     int mid=(p->l+p->r)/2;
     65     int ans=0;
     66     if(l<=mid)ans=max(ans,query(p->lc,l,r));
     67     if(r>mid)ans=max(ans,query(p->rc,l,r));
     68     return ans;
     69 }
     70 int Find(int u,int v){
     71     int tp1=top[u],tp2=top[v],ans=0;
     72     while(tp1!=tp2){
     73         if(dep[tp1]<dep[tp2]){
     74             swap(tp1,tp2);swap(u,v);
     75         }
     76         ans=max(ans,query(root,pos[tp1],pos[u]));
     77         u=fa[tp1];tp1=top[u];
     78     }
     79     if(u==v) return ans;
     80     if(dep[u]>dep[v]) swap(u,v);
     81     return max(ans,query(root,pos[u]+1,pos[v]));
     82 } 
     83 int main()
     84 {
     85     scanf("%d",&t);
     86     while(t--){
     87         memsett();
     88         scanf("%d",&n);
     89         for(int i=1,x,y,z;i<=n-1;i++){
     90             scanf("%d%d%d",&x,&y,&z);
     91             Add_Edge(x,y,z);Add_Edge(y,x,z);
     92         }
     93         DFS(1,0,1);
     94         GetTop(1,1);
     95         Build(root,1,p);
     96         for(int i=1;i<=2*n-2;i+=2){
     97             if(dep[e[i].v]<dep[e[i].u]) swap(e[i].v,e[i].u); 
     98             UpDate(root,pos[e[i].v],e[i].w);
     99         }
    100         char s[15];int u,v;
    101         while(scanf("%s",s)==1){
    102             if(s[0]=='D')break;
    103             scanf("%d%d",&u,&v);
    104             if(s[0]=='Q')printf("%d
    ",Find(u,v));
    105             else UpDate(root,pos[e[u*2-1].v],v);
    106         }
    107     }
    108     return 0;
    109 }

    AC:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 using namespace std;
      5 struct edge{
      6     int u,v,w,next;
      7 }e[20010];
      8 struct node{
      9     int l,r,val;
     10     node *lc,*rc;
     11 }*root=NULL;
     12 int t,n,m,head[10010],js,p;
     13 int fa[10010],son[10010],dep[10010],top[10010],pos[10010],siz[10010];
     14 // fa存他的父亲 son存他的重孩子 dep它的深度 top他所在重链的链顶 
     15 //pos在线段树中的位置 siz[v]以v为顶的子树的孩子数 
     16 void memsett()
     17 {
     18     js=0;p=0;
     19     memset(head,0,sizeof(head));
     20     memset(e,0,sizeof(e));
     21     memset(son,0,sizeof(son));
     22 }
     23 void add_edge(int u,int v,int w)
     24 {
     25     e[++js].u=u;e[js].v=v;e[js].w=w;
     26     e[js].next=head[u];head[u]=js;
     27 }
     28 void dfs(int u,int f,int d){
     29     fa[u]=f;dep[u]=d;siz[u]=1;
     30     for(int i=head[u];i;i=e[i].next){
     31         int v=e[i].v;
     32         if(v!=f){
     33             dfs(v,u,d+1);
     34             siz[u]+=siz[v];
     35             if(!son[u]||siz[son[u]]<siz[v])
     36               son[u]=v;
     37         }
     38     }
     39 }
     40 void gettop(int u,int tp)
     41 {
     42     top[u]=tp;pos[u]=++p;
     43     if(!son[u]) return;
     44     gettop(son[u],tp);
     45     for(int i=head[u];i;i=e[i].next)
     46     {
     47         int v=e[i].v;
     48         if(v!=son[u]&&v!=fa[u])
     49           gettop(v,v);
     50     }
     51 }
     52 void build(node * &pt,int l,int r){
     53      pt=new(node);
     54      pt->l=l;pt->r=r;pt->val=0;
     55      if(l==r){
     56          pt->lc=pt->rc=NULL;
     57          return ;
     58      }
     59      int mid=(l+r)/2;
     60      build(pt->lc,l,mid);
     61      build(pt->rc,mid+1,r);
     62 }
     63 void update(node * p,int ps,int val){
     64     if(p->l==p->r){
     65         p->val=val;return;
     66     }
     67     int mid=(p->l+p->r)/2;
     68     if(ps<=mid) update(p->lc,ps,val);
     69     else update(p->rc,ps,val);
     70     p->val=max(p->lc->val,p->rc->val);
     71 }
     72 int query(node * p,int l,int r)
     73 {
     74     if(l<=p->l&&p->r<=r)return p->val;
     75     int mid=(p->l+p->r)/2;
     76     int ans=0;
     77     if(l<=mid)ans=max(ans,query(p->lc,l,r));
     78     if(r>mid)ans=max(ans,query(p->rc,l,r));
     79     return ans;
     80 }
     81 int find(int u,int v)
     82 {
     83     int tp1=top[u],tp2=top[v],ans=0;
     84     while(tp1!=tp2)
     85     {
     86         if(dep[tp1]<dep[tp2])
     87         {
     88             swap(tp1,tp2);swap(u,v);
     89         }
     90         ans=max(ans,query(root,pos[tp1],pos[u]));
     91         u=fa[tp1];tp1=top[u];
     92     }
     93     if(u==v) return ans;
     94     if(dep[u]>dep[v]) swap(u,v);
     95     return max(ans,query(root,pos[u]+1,pos[v]));
     96 } 
     97 int main()
     98 {
     99     scanf("%d",&t);
    100     while(t--)
    101     {
    102         memsett();
    103         scanf("%d",&n);
    104         for(int i=1;i<=n-1;i++)
    105         {
    106             int x,y,z;
    107             scanf("%d%d%d",&x,&y,&z);
    108             add_edge(x,y,z);add_edge(y,x,z);
    109         }
    110         dfs(1,0,1);
    111         gettop(1,1);
    112         build(root,1,p);
    113         for(int i=1;i<2*n-2;i+=2)// 建边表时见了两遍 
    114         {
    115             if(dep[e[i].v]<dep[e[i].u]) swap(e[i].v,e[i].u);// 让v在下面 
    116             update(root,pos[e[i].v],e[i].w);
    117         }
    118         char s[15];int u,v;
    119         while(scanf("%s",s)==1)
    120         {
    121             if(s[0]=='D') break;
    122             scanf("%d%d",&u,&v);
    123             if(s[0]=='Q') printf("%d
    ",find(u,v));// 查询从u到v所经过的最大边权 
    124             else update(root,pos[e[u*2-1].v],v);// 将第u条边的权值修改为v 
    125         }
    126     }
    127     return 0;
    128 }
  • 相关阅读:
    get请求中文乱码问题
    JDBC
    SpringSecurity
    IDEA中创建项目
    Vue路由传参的几种方式
    vue-cli搭建与使用
    docker发布springboot项目
    css伪类的使用
    java实体类序列化与反序列化
    docker网络
  • 原文地址:https://www.cnblogs.com/suishiguang/p/6416087.html
Copyright © 2011-2022 走看看