• <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,對于任意兩個節點u,v,求出LCA(T,u,v)

             LCA的tarjan算法 (離線算法)
             //初始所有節點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的數組n,回答詢問RMQ(A,i,j),即A[i..j]中元素最小的數的下標


             將LCA問題轉化為RMQ問題

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


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

              詢問時 取k=log2(j-i+1)令A為從i開始的長度為2^k的塊的RMQ
                      令B為到j結束的長度為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)算法
              ………………………………


            未完待續…………



            ////////
            寫了個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 閱讀(143) 評論(0)  編輯 收藏 引用

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

            導航

            統計

            常用鏈接

            留言簿

            文章檔案(85)

            搜索

            最新評論

            • 1.?re: poj1426
            • 我嚓,,輝哥,,居然搜到你的題解了
            • --season
            • 2.?re: poj3083
            • @王私江
              (8+i)&3 相當于是 取余3的意思 因為 3 的 二進制是 000011 和(8+i)
            • --游客
            • 3.?re: poj3414[未登錄]
            • @王私江
              0ms
            • --jh818012
            • 4.?re: poj3414
            • 200+行,跑了多少ms呢?我的130+行哦,你菜啦,哈哈。
            • --王私江
            • 5.?re: poj1426
            • 評論內容較長,點擊標題查看
            • --王私江
            人人狠狠综合久久亚洲婷婷| 精品国产乱码久久久久久郑州公司| 精品国产福利久久久| 国产香蕉97碰碰久久人人| 久久精品成人| 午夜精品久久久久久久| 国产美女久久精品香蕉69| 久久久久国产精品嫩草影院| 囯产精品久久久久久久久蜜桃| 亚洲国产高清精品线久久| 久久天天躁狠狠躁夜夜不卡| 久久久久久久亚洲Av无码| 国产精品亚洲美女久久久| 精品久久久久久国产| 久久国产精品免费| 韩国免费A级毛片久久| 久久久久国产| 99久久精品免费观看国产| 精品国产乱码久久久久久人妻| 国内精品伊人久久久久网站| 日产精品久久久久久久性色| 久久久久九九精品影院| 久久成人国产精品| 亚洲AV无码久久精品蜜桃| 久久久人妻精品无码一区| 国产精品免费久久久久影院| 国内精品久久人妻互换| 亚洲AV成人无码久久精品老人 | 亚洲国产另类久久久精品小说| 99久久综合国产精品二区| 久久精品中文騷妇女内射| 一本一道久久综合狠狠老| 亚洲精品成人久久久| 久久久久97国产精华液好用吗| 99久久久久| 精品久久久久国产免费| 99久久国产主播综合精品 | 久久精品无码专区免费青青| 伊人久久综合成人网| 久久夜色精品国产噜噜亚洲AV| 亚洲人成精品久久久久|