标签:swap swa std ems color main algorithm wap const
题意:
一道很裸的LCA题
以一个点建树,两点间最短的距离可以转化为求两近公共祖先,最短距离,depth[x]-depth[l]+depth[y]-depth[l]
在dfs求得每个点到顶点距离
#include<iostream> #include<cstring> #include<algorithm> #include<vector> using namespace std; const int maxn=4e4+5; const int maxbit=15; struct edge { int to; int val; }; int father[maxn][maxbit]; int depth[maxn]; int dis[maxn];vector<edge>G[maxn]; int lg[maxn]; void dfs(int nowp,int fa) { depth[nowp]=depth[fa]+1; father[nowp][0]=fa; for(int j=1;j<=lg[depth[nowp]];j++) father[nowp][j]=father[father[nowp][j-1]][j-1]; for(int i=0;i<G[nowp].size();i++) { edge e=G[nowp][i]; if(e.to!=fa) { dis[e.to]=dis[nowp]+e.val;//算距离 dfs(e.to,nowp); } } } int lca(int u,int v) { if(depth[u]<depth[v]) swap(u,v); while(depth[u]!=depth[v]) u=father[u][lg[depth[u]-depth[v]]]; if(u==v)return u; for(int j=lg[depth[u]];j>=0;j--) { if(father[u][j]!=father[v][j]) { u=father[u][j]; v=father[v][j]; } } return father[u][0]; } int main() { lg[0]=-1; for(int i=1;i<maxn;i++) lg[i]=lg[i>>1]+1; int t; scanf("%d",&t); while(t--) { memset(father,0,sizeof father); memset(depth,0,sizeof depth); memset(dis,0,sizeof dis); int n,m; scanf("%d%d",&n,&m); int x,y,k; for(int i=1;i<n;i++) { scanf("%d%d%d",&x,&y,&k); G[x].push_back({y,k}); G[y].push_back({x,k}); } dfs(1,0); while(m--) { scanf("%d%d",&x,&y); int l=lca(x,y); printf("%d\n",(dis[x]-dis[l])+(dis[y]-dis[l])); } } return 0; }
标签:swap swa std ems color main algorithm wap const
原文地址:https://www.cnblogs.com/flyljz/p/11687493.html