LCA最近公共祖先——tarjan算法

来源:互联网 发布:域名服务器是什么 编辑:程序博客网 时间:2024/05/22 05:02

tarjan算法求最近公共祖先,理论详见http://www.nocow.cn/


#include <iostream>#include <fstream>using namespace std;/**    LCA 最近公共祖先 tarjan算法    并查集+dfs    离线算法 先读入所有查询问题,并不按顺序给出结果。    算法流程    I.  vis[i]记录节点i是否被访问。        首先进行dfs,tarjan(i)。        置vis[i] = 1,father[i] = i。    II. 对所有与节点i有关的查询(i,j)进行查询处理        若节点已经访问了,vis[j] == 1,则可以找到(i,j)的LCA。        LCA(i,j) = getfather(j)。    III.对所有节点i的儿子j,若vis[j] == 0        则tarjan(j);        且father[j] = i;**/int vis[100],adj[100][100],n,m,q,father[100],que[100][100],anc[100][100];long adj_len[100],que_len[100];long find(long i){    if(father[i] == i) return i;    else return find(father[i]);}void tarjan(long i){    long j;    vis[i] = 1;    father[i] = i;    /**先处理与i有关的查询**/    for(j=1;j<=que_len[i];j++)        if(vis[que[i][j]] == 1)        {            anc[i][que[i][j]] = find(que[i][j]);            cout<<i<<" "<<que[i][j]<<" "<<anc[i][que[i][j]]<<endl;        }    /**再处理i的所有儿子**/    for(j=1;j<=adj_len[i];j++)        if(vis[adj[i][j]] == 0)        {            tarjan(adj[i][j]);            father[adj[i][j]] = father[i];          /**此处要更新father[j]!!!**/        }    return;}int main(){    ifstream fin("d.in");    long i,j,k,t;    fin>>n;    memset(adj_len,0,sizeof(adj_len));    memset(adj,0,sizeof(adj));    memset(que_len,0,sizeof(que_len));    memset(que,0,sizeof(que));    for(i=1;i<=n;i++)    {        fin>>m>>k;        for(j=1;j<=k;j++)        {            fin>>t;            adj[m][++adj_len[m]] = t;        }    }    fin>>q;    for(i=1;i<=q;i++)    {        fin>>j>>k;        que[j][++que_len[j]] = k;        que[k][++que_len[k]] = j;    }    tarjan(1);    cout<<"end";    return 0;}



原创粉丝点击