• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            LCA&RMQ

            LCA問題
             給定一棵有根樹T,對于任意兩個節(jié)點(diǎn)u,v,求出LCA(T,u,v)

             LCA的tarjan算法 (離線算法)
             //初始所有節(jié)點(diǎn)color為WHITE
             void LCA(u)
             {
              MAKE_SET(u);
              ancester[FIND_SET(u)]=u;
              for(u的每個兒子v)
              {
               LCA(v);
               UNION(u,v);
               ancester[FIND_SET(u)]=u;
              }
              color[u]=BLACK
              for(Q(u)中的所有元素)
              {
               if(color[v]==BLACK)
               printf("LCA(%d,%d)=%d\n",u,v,ancester[FIND_SET(v)]);
              }
             }


             MAKE_SET(u)表示建立一個只有u的集合,且u為集合的代表元
             FIND_SET(u)表示找出集合的代表元
             UNION(u,v) 表示合并u,v所在的集合


            RMQ問題
             給定一個長度為n的數(shù)組n,回答詢問RMQ(A,i,j),即A[i..j]中元素最小的數(shù)的下標(biāo)


             將LCA問題轉(zhuǎn)化為RMQ問題

              1.DFS遍歷樹,記錄遍歷到的節(jié)點(diǎn)E[1..2n-1],
                并用R[i]表示E數(shù)組中第一個值為i的元素的下標(biāo)
              2.對于任意 R[u]<R[v] ,dfs中第一次訪問u到第一次訪問v的路徑是E[R[u]..R[v]]
                并且其中深度最小的節(jié)點(diǎn)一定是u,v的LCA
              3.令數(shù)組L[i]表示節(jié)點(diǎn)E[i]的深度,那么當(dāng)R[u]<R[v]時,LCA(T,u,v)=RMQ(L,R[u],R[v]);
             轉(zhuǎn)換后的RMQ問題比較特殊,相鄰兩個元素的相差1或-1,這樣的問題成為+_1-RMQ


             一般RMQ的Spare Table(ST) 算法
              d[i,j]表示從i開始長度為2^j的區(qū)間的RMQ,
              則有遞推公式 d[i,j]=min(d[i][j-1],d[i+2^(j-1),j-1]),即用兩個相鄰的長度為2^(j-1)
              的區(qū)間來分形長度為2^j的區(qū)間    預(yù)處理時間復(fù)雜度為O(nlogn)

              詢問時 取k=log2(j-i+1)令A(yù)為從i開始的長度為2^k的塊的RMQ
                      令B為到j(luò)結(jié)束的長度為2^k的塊的RMQ
               則RMQ(i,j)=min(A,B),
               即 k=log2(j-i+1),RMQ[i,j]=min(d[i,k],d[j-2^k+1,k])

             +_1-RMQ的O(n)-O(1)算法
              ………………………………


            未完待續(xù)…………



            ////////
            寫了個lca的代碼
            不知道對不對
            #include<stdio.h>
            #include<string.h>
            #include<math.h>
            #define maxn 505
            #define black 1
            #define white 0
            int father[maxn],ancester[maxn];
            int color[maxn];
            struct node
            {
                int v,next;
            } edge[maxn*maxn];
            int p[maxn];
            int n,e,m;
            int root;
            void add(int u,int v)
            {
                edge[e].v=v;
                edge[e].next=p[u];
                p[u]=e++;
            }
            int find(int u)
            {
                if (u==father[u]) return u;
                else 
             {
              father[u]=find(father[u]);
             }//路徑壓縮
                return father[u];
            }
            void union1(int u,int v)
            {
                int tmp,tmp1;
                tmp=find(u);
                tmp1=find(v);
                father[tmp1]=tmp;
            }
            void lca(int u)
            {
                int i,v,v1;
                father[u]=u;
                ancester[find(u)]=u;
                for(i=p[u]; i!=-1; i=edge[i].next)
                {
                    v=edge[i].v;
                    lca(v);
                    union1(u,v);
                    ancester[find(u)]=u;
                }
                /*for(i=p1[u]; i!=-1; i=edge1[i].next)
                {
                    v1=edge1[i].v;
                    if (color[v1]==black)
                        printf("LCA(%d,%d)=%d\n",u,v1,ancester[find(v)]);
                }*/
                color[u]=black;
             for(i=1;i<=n;i++)
              if(i!=u)
             {
              if (color[i]==black)
              {
               printf("LCA(%d,%d)=%d\n",u,i,ancester[find(i)]);
              }
             }
            }
            int main()
            {
                int a,b,i;
                scanf("%d%d",&n,&m);
                scanf("%d",&root);
                memset(p,-1,sizeof(p));
                e=0;
                for(i=1; i<=m; i++)
                {
                    scanf("%d%d",&a,&b);
                    add(a,b);
                }
                for(i=1; i<=n; i++) father[i]=i;
                memset(color,white,sizeof(color));
                lca(1);
                return 0;
            }

            posted on 2012-04-30 11:39 jh818012 閱讀(142) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            <2025年7月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            導(dǎo)航

            統(tǒng)計

            常用鏈接

            留言簿

            文章檔案(85)

            搜索

            最新評論

            • 1.?re: poj1426
            • 我嚓,,輝哥,,居然搜到你的題解了
            • --season
            • 2.?re: poj3083
            • @王私江
              (8+i)&3 相當(dāng)于是 取余3的意思 因為 3 的 二進(jìn)制是 000011 和(8+i)
            • --游客
            • 3.?re: poj3414[未登錄]
            • @王私江
              0ms
            • --jh818012
            • 4.?re: poj3414
            • 200+行,跑了多少ms呢?我的130+行哦,你菜啦,哈哈。
            • --王私江
            • 5.?re: poj1426
            • 評論內(nèi)容較長,點(diǎn)擊標(biāo)題查看
            • --王私江
            性高湖久久久久久久久| 久久夜色精品国产噜噜麻豆| 99久久99久久| 精品久久久久久久久中文字幕| 国产精品久久久久无码av | 中文字幕久久亚洲一区| 久久精品国产只有精品66| 国产精品免费久久久久影院| 色99久久久久高潮综合影院| 久久大香萑太香蕉av| 无码人妻久久一区二区三区免费| 色88久久久久高潮综合影院| 久久国产精品久久国产精品| 天天综合久久一二三区| 久久亚洲精精品中文字幕| 日本久久久精品中文字幕| 欧美大战日韩91综合一区婷婷久久青草| 精品无码久久久久久午夜| 色诱久久久久综合网ywww| 国产激情久久久久影院老熟女免费| 久久精品国产亚洲5555| 精产国品久久一二三产区区别| 亚洲国产精品无码久久久不卡| 色综合久久无码中文字幕| 欧美一区二区三区久久综| 亚洲综合婷婷久久| 77777亚洲午夜久久多喷| 精品午夜久久福利大片| 模特私拍国产精品久久| 久久精品国产福利国产秒| 久久福利资源国产精品999| 久久国产精品久久| 亚洲国产精品无码久久久秋霞2 | 久久久久亚洲精品无码网址 | 久久久久亚洲AV成人片| 精品久久久久久久久久久久久久久| 久久激情亚洲精品无码?V| 国产精品久久久天天影视| 午夜天堂av天堂久久久| 伊人久久大香线蕉成人| 99久久精品免费|