[SinGuLaRiTy] 复习模板-树
Posted SinGuLaRiTy2001
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SinGuLaRiTy] 复习模板-树相关的知识,希望对你有一定的参考价值。
【SinGuLaRiTy-1041】 Copyright (c) SinGuLaRiTy 2017. All Rights Reserved.
计算树的直径
//方法:任选一个点作为起点进行一次BFS,找到最远点u。再以u为起点做一次BFS,找最长路即直径。 queue<int>point; void bfs(int a,int dis[]) { memset(dis,inf,sizeof dis); dis[a]=0; point.push(a); int v ,u ; while(!point.empty()) { u=point.front(); point.pop(); for(node *p=adj[u];p!=NULL;p=p->next) if(dis[(v=p->v)]>dis[u]+p->w) { dis[v]=dis[u]+p->w; point.push(v); } } } void solve()//输出直径长度 { bfs(1,dis); int flag=1; for(int i=2;i<=n;++i) if(dis[flag]<dis[i]) flag=i; bfs(flag,dis2); int flag2=1; for(int i=2;i<=n;++i) if(dis2[flag2]<dis2[i]) flag2=i; printf("%d",dis2[flag2]); }
LCA-返回a,b两点间的最短边权
返回a,b两点之间的最短边权 void dfs(int u) { int v ; for(node *p=adj[u];p!=NULL;p=p->next) { v=p->v; f[v][0]=u ; dep[v]=dep[u]+1 ; dfs(v); } } void init() { dep[root]=0 ; dfs(root); f[root][0]=root ; for(int j=1;j<MAXK;++j) for(int i=1;i<=n;++i) f[i][j]=f[f[i][j-1]][j-1]; } void adjust(int &u,int val) { for(int j=MAXK-1;j>=0;--j) if(dep[f[u][j]]>=val) u=f[u][j]; } int solve(int u,int v) { if(dep[u]>dep[v])adjust(u,dep[v]); else if(dep[u]<dep[v])adjust(v,dep[u]); if(u==v)return u; for(int j=MAXK-1;j>=0;--j) if(f[u][j]!=f[v][j]) u=f[u][j] ,v=f[v][j]; return f[u][0]; }
LCA-tarjan算法
void tarjan(int u) { for(node *p=adj[u];p!=NULL;p=p->next) { tarjan(p->v); Union(p->v,u); } vis[u]=1; for(int i=1;i<=ask[u][0];++i) if(vis[ask[u][i]]==1) printf("%d\n",getroot(ask[u][i])); } void init() { scanf("%d",&m); while(m--) { scanf("%d%d",&a,&b); ask[a][++ask[a][0]]=b; ask[b][++ask[b][0]]=a; } for(int i=1;i<=n;++i) if(!in[i]) { tarjan(i); break; } }
以上是关于[SinGuLaRiTy] 复习模板-树的主要内容,如果未能解决你的问题,请参考以下文章