dfn[N][2],时间戳,标记dfs时访问改点的开始时间和结束时间。
根据时间戳,就能判断x点是否为y点的子孙。
然后考虑一下,dp[][],数组需要存什么东西。。
分情况讨论一下~
思路:http://fszxwfy.blog.163.com/blog/static/4401930820139804045831/
#include<stdio.h> #include<string.h> #include<math.h> #include<stdlib.h> #include<iostream> #include<algorithm> #include<queue> #include<vector> #include<set> #include<map> using namespace std; #define ll long long const int inf = 0x3f3f3f3f; const ll int64 = (ll)inf * inf; #define N 100010 int dfn[N][2],minson[N][2],mindes[N],fa[N]; vector<int> f[N]; int index; void dfs(int v,int fu) { int i,j,len,u; len=f[v].size(); fa[v]=fu; for(i=0;i<len;i++) { u=f[v][i]; if(u==fu) { f[v].erase(f[v].begin()+i); i--; len--; continue; } dfn[u][0]=index++; dfs(u,v); dfn[u][1]=index++; mindes[v]=min(mindes[v],mindes[u]); mindes[v]=min(mindes[v],u); if(u<minson[v][1]) { if(u<minson[v][0]) { minson[v][1]=minson[v][0]; minson[v][0]=u; } else minson[v][1]=u; } } } int find(int x,int y) { int l=0,r=f[y].size()-1,mid,u; while(1) { mid=(l+r)/2; u=f[y][mid]; if(dfn[u][0]<=dfn[x][0] && dfn[u][1]>=dfn[x][1]) return u; else if(dfn[x][0]>dfn[u][1]) l=mid+1; else r=mid-1; } } int main() { int t; scanf("%d",&t); while(t--) { int n,q,i,k,a,b; memset(minson,inf,sizeof(minson)); memset(mindes,sizeof(mindes)); scanf("%d%d",&n,&q); for(i=0;i<=n;i++) f[i].clear(); for(i=1;i<n;i++) { scanf("%d%d",&a,&b); f[a].push_back(b); f[b].push_back(a); } index=0; dfn[1][0]=index++; dfs(1,-1); dfn[1][1]=index++; int temp[2]; temp[0]=temp[1]=inf; int len=f[1].size(); int he=0; for(i=0;i<len;i++) { b=f[1][i]; a=min(b,mindes[b]); if(a<temp[1]) { if(a<temp[0]) { temp[1]=temp[0]; temp[0]=a; he=b; } else temp[1]=a; } } int x,y; while(q--) { scanf("%d%d",&x,&y); if(!(dfn[x][0]>dfn[y][0] && dfn[x][1]<dfn[y][1])) { if(f[y].size()==0) printf("no answers!\n"); else printf("%d %d\n",minson[y][0],mindes[y]); } else { int fx=find(x,y); if(y!=1) { if(fx!=minson[y][0]) printf("%d %d\n",min(fa[y],minson[y][0]),1); else printf("%d %d\n",minson[y][1]),1); } else { if(fx!=minson[y][0]) a=minson[y][0]; else a=minson[y][1]; if(he!=fx) b=temp[0]; else b=temp[1]; if(f[1].size()==1) printf("no answers!\n"); else printf("%d %d\n",b); } } } printf("\n"); } }原文链接:https://www.f2er.com/javaschema/285598.html