标签:tps int 模板 head oid div clu 结束 for
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define rll register ll 4 #define M 0x3f3f3f 5 #define For(i,l,r) for(int i=l;i<=r;i++) 6 using namespace std; 7 ll n,m,s,head[M],a[M],x,y,z,tot,k,t; 8 ll fa[M],d[M],top[M],size[M],id[M],ril[M]; 9 struct node1{ 10 ll to,nxt; 11 }e[M<<1]; 12 struct node2{ 13 ll l,r,sum,flag; 14 }tree[M<<1]; 15 16 inline ll read(){ 17 ll f=1,sum=0; 18 char ch=getchar(); 19 while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} 20 while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();} 21 return f*sum; 22 } 23 24 inline void add(ll x,ll y){ 25 e[++tot].to=y; 26 e[tot].nxt=head[x]; 27 head[x]=tot; 28 } 29 30 inline void dfs1(ll u){//第一遍dfs遍历树,预处理d深度,size此点子节点个数,fa其父节点 31 d[u]=d[fa[u]]+1; 32 size[u]=1; 33 for(rll i=head[u];i;i=e[i].nxt){ 34 if(e[i].to!=fa[u]){ 35 fa[e[i].to]=u; 36 dfs1(e[i].to); 37 size[u]+=size[e[i].to]; 38 } 39 } 40 } 41 42 inline void dfs2(ll u){//按照子节点个数多少划分轻重边,保证一个点只在一条链中。一般只用重边,轻边用不到。 43 ll t=0;//top即为此点所在重边的顶点 44 if(!top[u]) top[u]=u; 45 for(rll i=head[u];i;i=e[i].nxt){ 46 if(e[i].to!=fa[u]&&size[e[i].to]>t) t=e[i].to; 47 } 48 if(t){ 49 top[t]=top[u]; 50 dfs2(t); 51 } 52 for(rll i=head[u];i;i=e[i].nxt){ 53 if(e[i].to!=fa[u]&&e[i].to!=t) dfs2(e[i].to); 54 } 55 } 56 57 inline ll lca(ll x,ll y){//当两个点位于同一条重链上即结束操作。否则深度深的点跳到所在重链的上一个点,结束操作时深度浅的点的位置即为所求lca 58 while(top[x]!=top[y]){ 59 if(d[top[x]]<d[top[y]]) swap(x,y); 60 x=fa[top[x]]; 61 } 62 if(d[x]>d[y]) swap(x,y); 63 return x; 64 } 65 66 int main(){ 67 n=read(),m=read(),s=read(); 68 For(i,1,n-1) {x=read(),y=read(),add(x,y),add(y,x);} 69 dfs1(s),dfs2(s); 70 For(i,1,m){x=read(),y=read(),printf("%lld\n",lca(x,y));} 71 return 0; 72 }
标签:tps int 模板 head oid div clu 结束 for
原文地址:https://www.cnblogs.com/wi1d3on/p/11330922.html