来源:POJ1470
找了多少都是用的TATJAN,但是我是用的倍增法做的这个题
PS: DEBUG好辛苦
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
int n,Q;
int l,r;
const int MAXN = 910;
vector<int>tree[MAXN];
struct Node{
int k;
int id;
Node():k(0),id(0){}
}ans[MAXN];
bool son[MAXN];
int dp[MAXN][11];
int depth[MAXN];
void dfs(int cur,int pre,int d){
//cout<<cur<<" "<<pre<<" "<<d<<endl;
depth[cur]=d;
dp[cur][0]=pre;
//if(cur==5) cout<<"debug"<<dp[cur][0]<<endl;
for(int i=0;i<tree[cur].size();i++){
dfs(tree[cur][i],cur,d+1);
}
}
void ini(int rt){
dfs(rt,-1,0);
for(int k=1;k<=10;k++){
for(int i=1;i<=n;i++){
if(dp[i][k-1]<0){
//cout<<"d"<<endl;
dp[i][k]=-1;
}
else dp[i][k]=dp[dp[i][k-1]][k-1];
}
}
}
int LCA(int l,int r){
//cout<<"start: "<<l<<" "<<r<<endl;
if(depth[l]>depth[r]) swap(l,r);
for(int i=0;i<=10;i++){
//cout<<"debug ";
if((depth[r]-depth[l]>>i)&1){
//cout<<"debug: "<<r<<" ";
r=dp[r][i];
//cout<<r<<endl;
}
}
//DEBUG
//cout<<"hang: "<<l<<" "<<r<<endl;
if(r==l) return l;
for(int i=10;i>=0;i--){
if(dp[r][i]!=dp[l][i]){//否则一起向上
//cout<<"i: "<<i<<" "<<l<<" "<<r<<endl;
l=dp[l][i];
r=dp[r][i];
//cout<<"after : "<<i<<" "<<l<<" "<<r<<endl;
}
}
return dp[l][0];
}
int cmp(Node a,Node b){
return a.id<b.id;
}
int main(){
char ch;
while(scanf("%d",&n)!=EOF){
//cout<<"n= "<<n<<endl;
for(int i=1;i<=n;i++) tree[i].clear();
for(int i=0;i<=n;i++) {
ans[i].id=i;
ans[i].k=0;
}
memset(son,false,sizeof(son));
for(int i=0;i<n;i++){
int m,d,cnt=0;
scanf("%d",&m);
//cout<<m<<endl;
scanf("%c",&ch);
//cout<<ch<<endl;
scanf("%c",&ch);
//cout<<ch<<endl;
scanf("%d",&cnt);
//cout<<cnt<<endl;
scanf("%c",&ch);
//cout<<ch<<endl;
for(int i=0;i<cnt;i++){
scanf("%d",&d);
tree[m].push_back(d);
son[d]=1;
}
}
int rt;
for(int i=1;i<=n;i++){
if(!son[i]){
rt=i;
break;
}
}
ini(rt);
scanf("%d",&Q);
getchar();
while(Q--)
{
while(getchar()!='(');
scanf("%d%d",&l,&r);
//cout<<"Q"<<endl;
//cout<<l<<" "<<r<<endl;
int d=LCA(l,r);
//cout<<"d: "<<d<<endl;
ans[d].k++;
//ans[d].id=d;
while(getchar()!=')');
}
//cout<<"-----------------------"<<endl;
sort(ans+1,ans+n+1,cmp);
for(int i=1;i<=n;i++){
// cout<<ans[i].k<<endl;
if(ans[i].k){
// cout<<"ans: "<<endl;
cout<<ans[i].id<<":"<<ans[i].k<<endl;
}
}
}
return 0;
}