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


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


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

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            留言簿

            文章檔案(85)

            搜索

            最新評論

            • 1.?re: poj1426
            • 我嚓,,輝哥,,居然搜到你的題解了
            • --season
            • 2.?re: poj3083
            • @王私江
              (8+i)&3 相當(dāng)于是 取余3的意思 因?yàn)?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)題查看
            • --王私江
            亚洲国产精品久久久久婷婷软件 | 久久天堂电影网| 国产精品久久久久国产A级| 亚洲精品乱码久久久久久中文字幕| 亚洲国产另类久久久精品 | 久久黄视频| 久久香综合精品久久伊人| 亚洲精品白浆高清久久久久久| 狠狠久久亚洲欧美专区| 久久夜色精品国产www| 麻豆AV一区二区三区久久| 99久久精品久久久久久清纯 | 亚洲AV无码久久寂寞少妇| www亚洲欲色成人久久精品| 伊人精品久久久久7777| 国产精品久久免费| 久久久久久久波多野结衣高潮 | 国内精品久久国产大陆| 色天使久久综合网天天| 久久精品国产69国产精品亚洲| 色天使久久综合网天天| 亚洲午夜久久影院| 国产成人久久激情91| 99精品国产综合久久久久五月天| 国产成人精品久久亚洲高清不卡| 久久天天躁狠狠躁夜夜躁2O2O| 婷婷久久综合| 久久久久久久久久久免费精品| 久久成人国产精品二三区| 久久免费的精品国产V∧| 亚洲精品tv久久久久久久久久| 成人午夜精品久久久久久久小说 | 中文字幕热久久久久久久| 久久综合久久伊人| 久久精品国产欧美日韩| 国产—久久香蕉国产线看观看| 99久久精品国产麻豆| AV狠狠色丁香婷婷综合久久| 久久亚洲精品成人AV| 国产亚洲精久久久久久无码| 久久青青草原亚洲av无码app|