该算法的详细解释请戳:
http://www.cnblogs.com/Findxiaoxun/p/3428516.html
#include<cstdio> #include<algorithm> #include<cstring> #include<vector> using namespace std; ; int father[MAXN],ancestor[MAXN]; bool visit[MAXN]; int ans[MAXN]; vector<int> map[MAXN];//save the tree vector<int> query[MAXN];//save the query int n,t,root; bool indegree[MAXN];//the indegree to find the root int getfather(int v){//path compression if(father[v]==v)return v; return father[v]=getfather(father[v]); } void aunion(int u,int v){//?? int fv=getfather(v),fu=getfather(u); father[fv]=fu; } void LCA(int id){ int len=map[id].size(); ;i<len;i++){ int son=map[id][i]; LCA(son); aunion(id,son); } visit[id]=; len=query[id].size(); ;i<len;i++){ int son=query[id][i]; if(visit[son]) ans[father[getfather(son)]]++; } } void init(){ int x,y,z; ;i<=n;i++){ map[i].clear(); query[i].clear(); } memset(visit,,sizeof(visit)); memset(ans,,sizeof(ans)); memset(indegree,,sizeof(indegree)); ;i<=n;i++)father[i]=i; ;i<n;i++){ scanf("%d:(%d)",&x,&y); ;j<y;j++){ scanf("%d",&z); indegree[z]=; map[x].push_back(z); } } scanf("%d",&t); while(t--){//this method of the init is really clever while(getchar()!='('); scanf("%d%d",&x,&y); query[x].push_back(y); query[y].push_back(x); } while(getchar()!=')'); ;i<=n;i++)if(!indegree[i])root=i;//find the root;warning:the 0 } void output(){ ;i<=n;i++){ ) printf("%d:%d\n",i,ans[i]); } } int main(){ while(scanf("%d",&n)!=EOF){ init(); LCA(root); output(); } ; }