• <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 閱讀(142) 評論(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
            • 評論內容較長,點擊標題查看
            • --王私江
            色综合合久久天天给综看| 久久天天躁狠狠躁夜夜avapp| 亚洲色大成网站www久久九| 亚洲AV无码1区2区久久| 国产精品久久久久久一区二区三区| 精品999久久久久久中文字幕| 久久99精品国产麻豆不卡| 国产成人精品综合久久久久 | 色综合久久中文字幕综合网| 欧美国产成人久久精品| 青青青伊人色综合久久| 欧美日韩精品久久久久| 久久精品国产秦先生| 香蕉久久久久久狠狠色| 久久精品国产精品国产精品污 | 无码精品久久久久久人妻中字| 91精品国产综合久久婷婷| 欧美麻豆久久久久久中文| 国产精品久久久天天影视| 伊人久久大香线蕉av不变影院| 国产激情久久久久影院老熟女免费| 青青热久久国产久精品 | 久久这里只有精品视频99| 99久久精品国内| 亚洲国产欧洲综合997久久| 青青青青久久精品国产h久久精品五福影院1421 | 久久久久18| 91久久精品视频| 久久99国产精品二区不卡| 无码专区久久综合久中文字幕| 亚洲国产成人久久精品99| 久久免费观看视频| 久久亚洲天堂| 久久精品国产亚洲Aⅴ蜜臀色欲| 狠狠色丁香婷婷综合久久来| 久久国产亚洲精品无码| 亚洲中文久久精品无码ww16 | 久久久久一级精品亚洲国产成人综合AV区| 久久久久成人精品无码中文字幕| 99久久精品免费看国产一区二区三区| 亚洲欧洲久久av|