• <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>

            oyjpArt ACM/ICPC算法程序設(shè)計(jì)空間

            // I am new in programming, welcome to my blog
            I am oyjpart(alpc12, 四城)
            posts - 224, comments - 694, trackbacks - 0, articles - 6

            /*******************************
            圖的DFS信息構(gòu)建 by oyjpArt
            g矩陣: g[i][j] -> 0 : 無邊
                                     1 : 可重復(fù)訪問邊
                                    -1: 非可重復(fù)訪問邊
            說明:以為在無向圖中u->v訪問之后就不能再從v->u訪問了
                   故{u, v}訪問了之后{v, u}要置-1
                 如果是有向圖 則沒有這個(gè)規(guī)則
            gc矩陣:gc[i][j]-> 0 : 無邊
                              1 : 樹枝邊
                  2 : 反向邊
                  3 : 正向邊
                  4 : 交叉邊
            d數(shù)組: 頂點(diǎn)的開始訪問時(shí)間表
            f數(shù)組: 頂點(diǎn)的結(jié)束訪問時(shí)間表
            c數(shù)組: 頂點(diǎn)顏色表 0白色 -1灰色 1黑色
            p數(shù)組: 頂點(diǎn)的前驅(qū)表
            l數(shù)組: 頂點(diǎn)的L值(最頂層的祖先層數(shù))
            b數(shù)組: 頂點(diǎn)的度數(shù)表

            關(guān)于標(biāo)號(hào)函數(shù) LOW()
            LOW(U)代表的是與U以及U的子孫直接相連的結(jié)點(diǎn)的最高輩分(深度)
                                             d[U]                 U首次被訪問時(shí)
            LOW[U] =    min(LOW[U], d[W])    訪問邊{U,W}
                              min(LOW[U], LOW[S])  U的兒子S的關(guān)聯(lián)邊全部被訪問時(shí)
            /*******************************/
            const int maxn = 100;
            int n, g[maxn][maxn], gc[maxn][maxn];
            int d[maxn], f[maxn], l[maxn], p[maxn], c[maxn], b[maxn];
            int time;

            void dfs_visit(int u) {//遞歸搜索以U為根的深度優(yōu)先樹
             int v;
             c[u] = -1;         //置頂點(diǎn)為灰色//去掉這句之后適用于有向圖(后面設(shè)置不可訪問亦同)
             time++; d[u] = time, l[u] = time;
             for(v = 1; v<=n; v++)
              if(g[u][v] > 0)
               if(c[v] == 0)  {         //如果v是白色節(jié)點(diǎn)
                g[v][u] = -1;        //不可再訪問
                gc[u][v] = 1;        //樹枝邊
                b[u]++;              //度數(shù)
                p[v] = u;            //記錄父親節(jié)點(diǎn)
                dist_visit(v);       //遞歸搜索以v為根的深度優(yōu)先樹
                if(l[v] < l[u])      //v是u的后代
                 l[u] = l[v];     //u的兒子v的關(guān)聯(lián)邊搜索完后計(jì)算父親的low值
                g[v][u] = 1;         //恢復(fù)可訪問標(biāo)志
               }
               else {
                if(c[v] < 0) {       //若頂點(diǎn)為灰色
                 if(l[v] < l[u])  //u與v相連
                  l[u] = l[v];
                 gc[u][v] = 2;    //反向邊
                }
                else  {              //黑色
                 if(d[v] > d[u])
                  gc[u][v] = 3;         //正向邊
                 else
                  gc[u][v] = 4;         //交叉邊
                }
               }
             c[u] = 1;             //DFS完畢 置黑色吧
             time++; f[u] = time;
            }

            void dfs() {
             int u;
             memset(gc, 0, sizeof(gc));
             memset(c, 0, sizeof(c));
             memset(b, 0, sizeof(b));
             time = 0;
             for(u = 1; u <= n; u++)
              if(c[u] == 0) {
               p[u] = 0;
               dfs_visit(u);
              }
            }
            /*******************************
            DFS3大經(jīng)典應(yīng)用
            一: TOPO排序
             DFS之后按照結(jié)束訪問時(shí)間反向排序即可 如果在DFS過程中出現(xiàn)方向邊(成環(huán)) 則無法TOPO
            當(dāng)然我們還有一種經(jīng)典的TOPO方法 找0度節(jié)點(diǎn)迭代刪除法 o(M+N)的TC
            二: 求割點(diǎn)和橋
            判定規(guī)則1: 如果root節(jié)點(diǎn)又多于一個(gè)1子節(jié)點(diǎn) 則root是割點(diǎn)
            判定規(guī)則2: 如果一個(gè)節(jié)點(diǎn)u有某一個(gè)子節(jié)點(diǎn)v不含到u的祖先節(jié)點(diǎn)的后向邊 則u為割點(diǎn)
             即對(duì)于u的子節(jié)點(diǎn)v, u是割點(diǎn)的條件 (p[u] == 0 && b[v] > 1) || (p[u] > 0 && l[v] >= d[u])
            橋: 不屬于任何簡單回路的邊 "一牽動(dòng)全身" l[v] > d[u]即是橋
            之所以不能等于 實(shí)際上等于的情況是存在2條以上的邊 自然就不是橋了~
             (注意加上割點(diǎn)表 以防重復(fù)輸出)
            三: 求有向圖的極大強(qiáng)連通分支
            1.對(duì)圖進(jìn)行DFS遍歷 遍歷中記下所有的結(jié)束時(shí)間A[i].遍歷的結(jié)果是構(gòu)建的一座森林W1
              我們對(duì)W1中的每棵樹G進(jìn)行步驟2到步驟3的操作
            2.改變圖G中每一條邊的方向 構(gòu)造出新的有向圖Gr
            3.按照A[i]由小到大的順序?qū)r進(jìn)行DFS遍歷.遍歷的結(jié)果是構(gòu)建了新的樹林W2.
              W2中每棵樹上的頂點(diǎn)構(gòu)成了有向圖的極大強(qiáng)連通分支
            /*******************************/
            //一個(gè)更加簡潔的程序框架(來自<<算法藝術(shù)與信息學(xué)競賽>>)-------
            這里面的Ancestor相當(dāng)于上面所說的LOW
            Procedure DFS(節(jié)點(diǎn)編號(hào)k, k的父親節(jié)點(diǎn)編號(hào)father, deep:integer)
            var i, tot : integer;
            begin
              C[k] = -1; {灰色}
              D[k] = deep; {記錄深度}
              Ancestor[k] = deep, tot = 0;

              for i = 1->n
              begin
                  if(節(jié)點(diǎn)i和k相連) and (i != father) and (Ci = -1)
                 then Ancestor[k] = Min(Ancestor[k], Di);
               if(節(jié)點(diǎn)i與k相連) and (Ci = 0) then
               begin
              DFS(i, k, deep + 1);
                tot++, Ancestor[k] = Min(Ancestor[k], Ancestor[i]);
                if(k == Root) and (tot > 1) or
               ( (k != Root) and (Ancestor[i] >= D[k]) )
               then Cut[k] = true;
                if(Ancestor[i] > D[k]) then Brige[k][i] = true
                  end
              end
              C[k] = 1; //黑色
              time++, A[i] = time;
            end;
            //-----------------------------------------------------------

            Feedback

            # re: 圖的DFS信息構(gòu)建+割點(diǎn),橋,極大連通子圖三大法寶  回復(fù)  更多評(píng)論   

            2007-05-20 21:49 by YPP
            你好,我是ACM新手。
            請(qǐng)問,在ACM比賽中遇到有關(guān)圖的問題時(shí)是用鄰接表好還是鄰接矩陣好?我覺得兩個(gè)都有不方便的地方。
            比如輸入格式要求如下(頂點(diǎn) 與該頂點(diǎn)相鄰的頂點(diǎn)數(shù) 與該頂點(diǎn)相鄰的頂點(diǎn)):
            A 3 B C D
            B 2 A C
            C 1 D
            D 2 A B

            # re: 圖的DFS信息構(gòu)建+割點(diǎn),橋,極大連通子圖三大法寶  回復(fù)  更多評(píng)論   

            2007-05-21 13:53 by oyjpart
            下面我用n代表點(diǎn) m代表邊
            鄰接表:訪問任任兩點(diǎn)之間的邊最壞o(n) 遍歷一個(gè)點(diǎn)的所有邊o(該點(diǎn)的度數(shù))
            鄰接矩陣:訪問任兩點(diǎn)之間的邊o(1) 但是遍歷一個(gè)點(diǎn)的所有邊o(n)
            由此可以看出 選擇是有目的的
            第一 對(duì)于稀疏圖 有時(shí)候內(nèi)存不夠用 不得不待用鄰接表
            第二 對(duì)于比較密集的圖 鄰接表無甚優(yōu)勢
            第三 如果不需要在稀疏圖中經(jīng)常性的遍歷一個(gè)點(diǎn)的所有邊 鄰接矩陣是仍首選的

            看到你的輸入數(shù)據(jù)似乎用鄰接矩陣比較好

            # re: 圖的DFS信息構(gòu)建+割點(diǎn),橋,極大連通子圖三大法寶  回復(fù)  更多評(píng)論   

            2007-05-22 20:23 by YPP
            非常感謝你的解答。
            我那輸入數(shù)據(jù),我覺得用鄰接矩陣挺麻煩的。因?yàn)橹挥兴袛?shù)據(jù)輸入完畢才確定圖所有的頂點(diǎn),不太好處理

            # re: 圖的DFS信息構(gòu)建+割點(diǎn),橋,極大連通子圖三大法寶  回復(fù)  更多評(píng)論   

            2007-05-23 13:24 by oyjpart
            不管他 開靜態(tài)的二維數(shù)組滿足題目最大頂點(diǎn)數(shù)即可
            如果題目沒有說明而且你熟悉stl的話 你就用二維vector

            # re: 圖的DFS信息構(gòu)建+割點(diǎn),橋,極大連通子圖三大法寶  回復(fù)  更多評(píng)論   

            2007-12-18 13:04 by robber
            非常感謝!
            對(duì)這個(gè)經(jīng)典問題我思考一天了。對(duì)割點(diǎn)、橋等與這個(gè)算法的深入聯(lián)系都沒發(fā)現(xiàn),現(xiàn)在好了。

            # re: 圖的DFS信息構(gòu)建+割點(diǎn),橋,極大連通子圖三大法寶  回復(fù)  更多評(píng)論   

            2007-12-18 14:16 by alpc12
            不用謝 呵呵
            欧美牲交A欧牲交aⅴ久久| 久久精品成人免费观看97| 久久男人AV资源网站| 91精品久久久久久无码| 精品人妻久久久久久888| 亚洲AV日韩精品久久久久久 | 久久毛片一区二区| 久久99精品免费一区二区| 狠狠色丁香久久婷婷综| 久久精品国产精品国产精品污 | 亚洲va久久久噜噜噜久久| 亚洲va久久久噜噜噜久久天堂| 欧美日韩精品久久久久| 成人午夜精品无码区久久| 精品久久久久香蕉网| 亚洲国产精品婷婷久久| 久久亚洲国产精品五月天婷| 久久精品久久久久观看99水蜜桃| 久久午夜无码鲁丝片| 久久夜色精品国产亚洲| 久久久久亚洲精品中文字幕| 久久久一本精品99久久精品88| 国产亚洲色婷婷久久99精品| 91久久成人免费| 日韩精品久久久久久久电影蜜臀| 久久精品国产亚洲欧美| 欧美无乱码久久久免费午夜一区二区三区中文字幕 | 国产综合精品久久亚洲| 午夜精品久久久久久久无码| 亚洲中文字幕无码久久精品1 | 久久久亚洲欧洲日产国码aⅴ| 国产精品99久久精品爆乳| 一本大道久久香蕉成人网| 久久久精品2019免费观看| 激情久久久久久久久久| 久久久久久久久久久久中文字幕| 狠狠色丁香婷婷综合久久来来去| 亚洲午夜久久久久久久久久| 久久久久亚洲AV无码专区桃色| 97精品国产91久久久久久| 久久影院午夜理论片无码|