zoukankan      html  css  js  c++  java
  • POJ 1470 Closest Common Ancestors(LCA 最近公共祖先)

      其实这是一个裸求LCA的题目,我使用的是离线的Tarjan算法,但是这个题的AC对于我来说却很坎坷……首先是RE,我立马想到数组开小了,然后扩大了数组,MLE了……接着把数组调整适当大小,又交了一发,嗯?居然WA了,一定是我姿势不对,我换个编译器交一下,结果还是WA……这就比较尴尬了,最后审题目,发现了,我以为第一个输入的点就是根节点,其实不是,我们还需要找到入度为0的点来处理,这里做一个标记就可以了。还有就是题目的输入稍微有点坑,尤其是第二次输入,题目中说忽略所有空白,这就需要比较好的处理方法了,我采用的是while的方法,当然方法肯定是有很多的。代码如下:

    #include<cstring>
    #include<cstdio>
    #include<iostream>
    using namespace std;
    #define N 1010
    int head[N],qhead[N],n,tot,qtot;
    struct Edge{
        int to,nxt;
    }edge[N*N];
    void addedge(int a,int b){
        edge[tot].to = b;
        edge[tot].nxt = head[a];
        head[a] = tot++;
    }
    Edge query[N*N];
    void addquery(int a,int b){
        query[qtot].to = b;
        query[qtot].nxt = qhead[a];
        qhead[a] = qtot++;
    }
    int vis[N],fa[N],ans[N];
    int Find(int x){
        return x == fa[x] ? fa[x] : fa[x] = Find(fa[x]);
    }
    void tarjan(int u){
        vis[u] = 1;
        fa[u] = u;
        int v,LCA;
        for(int i = qhead[u];i != -1;i = query[i].nxt){
            v = query[i].to;
            if(vis[v]){
                LCA = Find(v);
                //printf("%d->%d LCA = %d
    ",u,v,LCA);
                ans[LCA]++;
            }
        }
        for(int i = head[u];i != -1;i = edge[i].nxt){
            v = edge[i].to;
            if(!vis[v]){
                tarjan(v);
                fa[v] = u;
            }
        }
        return ;
    }
    int main(){
        int a,b,m,num,anc,mark[N];
        while(~scanf("%d",&n)){
            tot = 0;
            memset(head,-1,sizeof(head));
            memset(mark,0,sizeof(mark));
            for(int i = 1;i <= n;i++){
                scanf("%d:(%d) ",&a,&num);
                for(int j = 0;j < num;j++){
                    scanf("%d",&b);
                    mark[b] = 1;
                    addedge(a,b);
                }
    //            for(int j = head[a];j != -1;j = edge[j].nxt){
    //                printf("%d->%d
    ",a,edge[j].to);
    //            }
                fa[i] = i;
            }
            for(int i = 1;i <= n;i++){
                if(!mark[i]){
                    anc = i;
                    break;
                }
            }
            memset(qhead,-1,sizeof(qhead));
            qtot = 0;
            scanf("%d",&m);
          //  getchar();
            char ch; int cnt = 0;
            while(~scanf("%c",&ch)){
                if(ch == '('){
                    scanf("%d %d)",&a,&b);
                    addquery(a,b);
                    addquery(b,a);
                    cnt++;
                }
                if(cnt==m) break;
            }
            memset(vis,0,sizeof(vis));
            memset(ans,0,sizeof(ans));
            tarjan(anc);
            for(int i = 1;i <= n;i++){
                if(ans[i]) printf("%d:%d
    ",i,ans[i]);
            }
        }
        return 0;
    }
  • 相关阅读:
    VS2005快捷键(转)
    codeSmish使用《转》
    WinForm TextBox数据绑定
    NetTiers抛出"Unable To Load NetTiersServiceSection“的异常
    DELPHi第三方控件使用方法(摘录)
    遠程連接操作
    不同服务器数据库之间的数据操作
    delphi 关闭 MDI 子窗体
    VSS使用手册(转)
    delphi 快捷键
  • 原文地址:https://www.cnblogs.com/jifahu/p/5593912.html
Copyright © 2011-2022 走看看