欢迎使用本站,预祝练习时长两年半的选手们到成功! [本模块信息来自tem/def/head]

class122-123 zxy 树链剖分02

时间:2024-07-26 22:11 作者:admin 点击:
#define MAXN 200050 const int MAXN = 200050; //邻接表存树 struct edge{ int to; //边指向的顶点 int next; //下一条边在链表中的位置 }; vectoredge es; int n,m,r,p,val[MAXN],u,v,x,y,c; int head[MAXN];//记录每个节点的边

#define MAXN 200050

const int MAXN = 200050;

//邻接表存树

struct edge{

   int to;   //边指向的顶点

   int next; //下一条边在链表中的位置

};

vector<edge> es;

int n,m,r,p,val[MAXN],u,v,x,y,c;

int head[MAXN];//记录每个节点的边的链表表头

int size[MAXN],fa[MAXN],dep[MAXN],son[MAXN];//节点重量,父节点,节点深度,重儿子

void addedge(int u,int v){

   static int edgeid=1; // 边的索引

   // es[edgeid].to=v;     // 记录目标顶点

   // es[edgeid].next=head[u];  //将新边记录在u点的边的链表头部

   es.push_back({v,head[u]});

   head[u]=edgeid++; //更新头部

}

void dfshld(int u,int f){

   size[u]=1;

   for(int i=head[u];i!=0;i=es[i].next){

       int v=es[i].to;

       if(v==f) continue;

       dep[v]=dep[u]+1;

       fa[v]=u;

       dfshld(v,u);

       size[u]+=size[v];

       if(size[v]>size[son[u]]){

           son[u]=v;

       }

   }

}

int top[MAXN],id[MAXN],rev[MAXN];

//链头,id:当前节点在序列中的编号,rev:当前这个编号对应的是第几个节点

int total=0;

void dfspos(int u,int t){

   top[u]=t; //将u的链头标记到t

   id[u]=++total; //当前节点是序列中的total节点

   rev[total]=u;  //当前total节点是u

   if(!son[u]) return ;

   dfspos(son[u],t); //沿着重儿子进行dfs

   for(int i=head[u];i!=0;i=es[i].next){ //将其他儿子也存放到线性序列中

       int v=es[i].to;

       if(v!=fa[u]&&v!=son[u]){

           dfspos(v,v);

       }

   }

}

int main(){

   cin>>n>>m>>r>>p;

   for(int i=1;i<=n;i++) cin>>val[i];

   for(int i=1;i<n;i++){

       cin>>u>>v;

       addedge(u,v);

       addedge(v,u);

   }

   dfshld(r,0);

   dfspos(r,r);

   输出top、id、rev三个数组,验证数据剖分是否正确。

   思考这个树形结构如何通过剖分后的数据进行线段树的构造。

   /*

   while(m--){

       cin>>c;

       switch(c){

           case 1:break;

           case 2:break;

           case 3:break;

           case 4:break;

       }

   }*/

   return 0;

}

(责任编辑:admin)
    顶一下
    (0)
    0%
    踩一下
    (0)
    0%