POJ1330Nearest Common Ancestors最近公共祖先LCA问题

用的离线算法Tarjan

该算法的详细解释请戳

http://www.cnblogs.com/Findxiaoxun/p/3428516.html

做这个题的时候,直接把1470的代码copy过来,改了改输入输出。这个的难度比那个低。

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<vector>

using namespace std;

const int MAXN=10005;

int father[MAXN],ancestor[MAXN];

bool visit[MAXN];

int ans[MAXN];

vector<int> map[MAXN];//save the tree

int n,t,root,sx,sy;

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;

}

bool isit(int a,int b){

    if(a==sx&&b==sy)return true;

    return false;

}

void LCA(int id){

    int len=map[id].size();

    int son;

    for(int i=0;i<len;i++){

        son=map[id][i];

        LCA(son);

        aunion(id,son);

    }

    visit[id]=1;

    if(visit[sy]&&id==sx){

        printf("%d\n",father[getfather(sy)]);

        return;

    }else{//attention:this way

        if(visit[sx]&&id==sy){

            printf("%d\n",father[getfather(sx)]);

            return;

        }

    }



}

void init(){

    int x,y,z;

    scanf("%d",&n);

    //initialize all the vars

    for(int i=0;i<=n;i++){

        map[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-1;i++){

        scanf("%d%d",&x,&y);

        indegree[y]=1;

        map[x].push_back(y);

    }

    scanf("%d%d",&sx,&sy);

    for(int i=1;i<=n;i++)if(!indegree[i])root=i;//find the root;warning:the 0

}

int main(){

    int  t;

    scanf("%d",&t);

    while(t--){

        init();

        LCA(root);

    }

    return 0;

}

 

你可能感兴趣的:(REST)