poj 1986 Nearest Common Ancestors (LCA)

來源:互聯網
上載者:User

 

給出你一棵樹,最後一行詢問頂點a和頂點b的最近公用祖先

Tarjan離線尋找最近公用祖先:

                 搜到新的頂點,此頂點的臨時祖先就是上一層的頂點

                 直到搜到葉子就開始回溯,回溯的時候

                 從這點出發搜過的頂點的臨時祖先合并為這個頂點的上一層頂點

//Final   LCA離線演算法求最近公用祖先#include <stdio.h>#include <string.h>#include <stdlib.h>#include <algorithm>#include <vector>#define MAX 11000using namespace std;vector<int>Hash[MAX],Qes[MAX];int n,m,visit[MAX],ansetor[MAX],parent[MAX],fathernum[MAX];void Init(int n)      //並查集初始化{    for(int i=1;i<=n;i++)        parent[i]=i;}int Find(int x)       //並查集尋找和壓縮路徑{    int s,j;    s=x;    while(x!=parent[x])        x=parent[x];    while(s!=x)    {        j=parent[s];        parent[s]=x;        s=j;    }    return x;}void Union(int r1,int r2)   //並查集合并{    int R1,R2;    R1=Find(r1);    R2=Find(r2);    if(R1!=R2)        parent[R1]=R2;}void LCA(int u)       //LCA{    int i,size;    visit[u]=1;       ansetor[u]=u;    size=Hash[u].size();    for(i=0;i<size;i++)     //size()從0開始計算    {if(!visit[Hash[u][i]]){            LCA(Hash[u][i]);            Union(u,Hash[u][i]);            ansetor[Find(Hash[u][i])]=u;  }  //***可以是Find(u)或者Find(Hash[u][i]),因為已經合并了    }    size=Qes[u].size();    for(i=0;i<size;i++)         //size()從0開始計算    {        if(visit[Qes[u][i]])    //如果需要尋找的兩個點其中一個點之前被訪問過,                    //那麼此時它的祖先就是它們的最近公用祖先        {            m=ansetor[Find(Qes[u][i])];   //***只能是Find(Qes[u][i]),因為此時u和Qes[u][i]並未合并            return ;        }    }}int main(){    int a,b,i,t;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        Init(n);        memset(visit,0,sizeof(visit));        memset(fathernum,0,sizeof(fathernum));        for(i=1;i<=n;i++)        {            Qes[i].clear();            Hash[i].clear();        }        for(i=1;i<=n-1;i++)        {            scanf("%d%d",&a,&b);            Hash[a].push_back(b);  //表示a是b的父親            fathernum[b]++;        //記錄每個頂點父親的個數        }        scanf("%d%d",&a,&b);        Qes[a].push_back(b);       //需要尋找的兩點        Qes[b].push_back(a);       //需要尋找的兩點        for(i=1;i<=n;i++)        {            if(!fathernum[i])      //沒有父親結點的點既是整棵樹的根節點            {                LCA(i);printf("%d\n",m);                break;            }        }    }    return 0;}


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.