求两个点的最近公共祖先
直接反向建图,2个dfs完事。。
当然如果是多个询问 得用rmq/tarjan了。。
水只。。。
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <queue> #include <map> #include <set> #include <vector> using namespace std; int n,m; vector<int> mp[10005]; int path_x[10005]; int okx; int root; int oky; int path_y[10005]; int x,y; int vis[10005]; int dfs_find_Ancestors(int z,int path[],int &ok) { path[++ok]=z; if (z==root) return 0; else dfs_find_Ancestors(mp[z][0],path,ok); } int main() { int i; int t;cin>>t; while(t--) { cin>>n; for (i=1;i<=n;i++) mp[i].clear(); for (i=1;i<=n-1;i++) { scanf("%d%d",&x,&y); mp[y].push_back(x); vis[y]=1; } for (i=1;i<=n;i++) { if (vis[i]==0) { root=i;break; } } scanf("%d%d",&x,&y); okx=oky=0; dfs_find_Ancestors(x,path_x,okx); dfs_find_Ancestors(y,path_y,oky); /* for (i=1;i<=okx;i++) { printf("%d ",path_x[i]); } printf("\n"); for (i=1;i<=oky;i++) { printf("%d ",path_y[i]); } printf("\n"); */ memset(vis,0,sizeof(vis)); for (i=1;i<=okx;i++) { vis[path_x[i]]=1; } int ans=-1; for (i=1;i<=oky;i++) { if (vis[path_y[i]]==1) { ans=path_y[i]; break; } } printf("%d\n",ans); } return 0; }