您的位置:首页 > 其它

POJ1470Closest Common Ancestors 最近公共祖先LCA 的 离线算法 Tarjan

2013-11-18 17:07 204 查看
该算法的详细解释请戳:

/article/7043942.html

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int MAXN=905;
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();
for(int i=0;i<len;i++){
int son=map[id][i];
LCA(son);
aunion(id,son);
}
visit[id]=1;
len=query[id].size();
for(int i=0;i<len;i++){
int son=query[id][i];
if(visit[son])
ans[father[getfather(son)]]++;
}

}
void init(){
int x,y,z;
for(int i=0;i<=n;i++){
map[i].clear();
query[i].clear();
}
memset(visit,0,sizeof(visit));
memset(ans,0,sizeof(ans));
memset(indegree,0,sizeof(indegree));
for(int i=0;i<=n;i++)father[i]=i;
for(int i=0;i<n;i++){
scanf("%d:(%d)",&x,&y);
for(int j=0;j<y;j++){
scanf("%d",&z);
indegree[z]=1;
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()!=')');
for(int i=1;i<=n;i++)if(!indegree[i])root=i;//find the root;warning:the 0
}
void output(){
for(int i=1;i<=n;i++){
if(ans[i]!=0)
printf("%d:%d\n",i,ans[i]);
}

}
int main(){
while(scanf("%d",&n)!=EOF){
init();
LCA(root);
output();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: