LCA(最小公共祖先节点问题)POJ1330
//Tarjan算法求LCS(树中的最小公共祖先节点)(离线) //if node 被标记过,说明节点已经被探索过,所以节点路径已经形成 //先把子树的query解决,只有把子树的儿子节点访问完毕才回溯并查集 #include<iostream> #include<cstdio> #include<vector> #include<cstring> using namespace std; const int maxn = 1e4 +15; vector<int> Grape[maxn],q[maxn]; bool rudu[maxn];//judge 是否是入度是否为0 if 0 则 root bool vis[maxn]; int node1,node2,T,n; int merage[maxn];//缩点 int find(int node) { if(node!=merage[node]) merage[node] = find(merage[node]); return merage[node]; } int ans; void Tarjan(int u)//返回LCS { for(int i=0;i!=Grape[u].size();++i) { int v = Grape[u][i]; Tarjan(v); merage[v] = u; } vis[u] = true; for(int j=0;j!=q[u].size();++j) { int v = q[u][j]; if(vis[v]) { ans = find(v); return; } } } int main() { cin>>T; while(T--) { cin>>n; for(int i=1;i<=n;++i) { Grape[i].clear(); q[i].clear(); } memset(rudu,false,sizeof(rudu)); memset(vis,false,sizeof(vis)); for(int i=1;i<=n;++i) merage[i] = i; int u,v; for(int i=0;i!=n-1;++i) { cin>>u>>v; Grape[u].push_back(v); rudu[v] = true; }//构建树 int root; for(int i=1;i<=n;++i) if(!rudu[i]) root = i; cin>>node1>>node2; q[node1].push_back(node2); q[node2].push_back(node1); cout<<ans<<endl; } }
不怕万人阻挡,只怕自己投降。
posted on 2019-09-25 21:31 chengyulala 阅读(159) 评论(0) 编辑 收藏 举报