论文网
English Papers
万事OK网
发表论文
 
 首页 > IT文章 > 程序设计 >
经典的图论算法C++描述

[科技论文网] http://www.scipapers.com    2007-12-01  

    经典的图论算法C++描述

    作者:acumon

    本标程介绍了一些经典的图论算法,C++描述。

    #include < cstring >
    // 常量定义:
    const   int  maxV = 100 ;
    const   double  Inf = 1e100;
    // const int Inf=2000000000;
    // Graph类定义:
    template < class  T >
    struct  GraphMatrix {
        
    int  v;     // 顶点数
         int  e;     // 边数
        T a[maxV][maxV];     // 邻接矩阵
         void  init() {
            memset(a,
    0 , sizeof (a));
        }

        
    void  clear() {
            
    int  i,j;
            
    for (i = 0 ; i < v;  ++ i) {
                
    for (j = 0 ; j < v;  ++ j)
                    a[i][j]
    = Inf;
            }

        }

    }
    ;

    #include
    < list >
    using  std::list;
    template
    < class  T >
    struct  GraphList {
        
    int  v;
        
    int  e;
        list
    < T >  a[maxV];     // 邻接表
         void  clear() { // clear()应在更改v之前进行
             int  i;
            
    for (i = 0 ; i < v; i ++ )
                a[i].clear();
        }

        
    ~ GraphList() {
            v
    = maxV;
            clear();
        }

    }
    ;

    namespace  bridgeNS {
    /* 解决:查找、打印桥
     *算法:DFS——O(E)
     *输入:连通图(表):g
     *输出:屏幕
     
    */

        GraphList
    < int >  g;
        
    int  cnt;
        
    int  pre[maxV];     // DFS顺序
         int  low[maxV];     // 最低前序编号:儿子low值的最小值
         void  _bridge( int  prnt,  int  w) {
            
    int  v; // son
            low[w] = pre[w] = cnt ++ ;
            std::list
    < int > ::iterator li;
            
    for (li = g.a[w].begin(); li != g.a[w].end();  ++ li) {
                v
    =* li;
                
    if (pre[v] ==- 1 ) {
                    _bridge(w,v);
                    
    if (low[w]  >  low[v]) low[w]  =  low[v];
                    
    if (low[v]  ==  pre[v])
                        printf(
    " %d-%d\n " ,w,v); // 找到桥
                }
    else   if (v != prnt  &&  low[w]  >  pre[v]) low[w]  =  pre[v];
            }

        }

        
    void  bridge() {
            cnt
    = 0 ;
            memset(pre,
    - 1 , sizeof (pre));
            _bridge(
    - 1 , 0 );
        }

    }
            

    namespace  GabowNS {
    /* 解决:强分量
     *算法:Gabow——O(E)
     *输入:图(表):g
     *输出:分量编号sc[]
     
    */

        GraphList
    < int >  g;
        
    int  cnt0, cnt1;
        
    int  sc[maxV]; // 分量编号
         int  pre[maxV];     // DFS顺序
         int  path[maxV],pp; // path栈
         int  stack[maxV],sp; //

        
    void  _SCdfsR( int  w) {
            pre[w]
    = cnt0 ++ ;
            stack[sp
    ++ ] = w;
            path[pp
    ++ ] = w;
            
    int  v; std::list < int > ::iterator li;
            
    for (li = g.a[w].begin(); li != g.a[w].end();  ++ li) {
                v
    =* li;
                
    if (pre[v] ==- 1 ) _SCdfsR(v);
                
    else   if (sc[v] ==- 1 ) {
                    
    while (pre[path[pp - 1 ]]  >  pre[v])  -- pp;
                }

            }

            
    if (path[pp - 1 !=  w)  return ;
            
    -- pp;
            
    do {
                sc[stack[
    -- sp]] = cnt1;
            }
    while (stack[sp]  !=  w);
            
    ++ cnt1;
        }

        
    void  init() {
            memset(pre,
    - 1 , sizeof (pre));
            memset(sc,
    - 1 , sizeof (sc));
            cnt0
    = cnt1 = 0 ;
            sp
    = pp = 0 ;
            
    int  i;
            
    for (i = 0 ; i < g.v;  ++ i) {
                
    if (sc[i] ==- 1 )
                    _SCdfsR(i);
            }

        }


        
    bool  isStrongReach( int  s,  int  t) {
            
    return  sc[s] == sc[t];
        }

    }


    namespace  PrimNS {
    /* 解决:最小生成树MST
     *算法:Prim——O(V^2)
     *输入:加权连通图(矩阵):g
     *输出:父节点st[],与其父之边的权重wt[]
     
    */

        GraphMatrix
    < double >  g;
        
    int  st[maxV];     // MST节点之父——用以保存MST
         double  wt[maxV + 1 ];     // 与其父的边的权重
         int  fr[maxV];     // 非树顶点的最近树顶点
         void  mst() {
            
    int  v, w, min;
            
    for (v = 0 ; v < g.v;  ++ v) {
                st[v]
    =- 1 ; fr[v] = v; wt[v] = Inf;
            }

            st[
    0 ] = 0 ; wt[g.v] = Inf;
            
    for (min = 0 ; min != g.v;) {
                v
    = min; st[v] = fr[v];
                
    for (w = 0 , min = g.v; w < g.v;  ++ w) {
                    
    if (st[w] ==- 1 ) {
                        
    if (g.a[v][w]  <  wt[w])
                            wt[w]
    = g.a[v][w], fr[w] = v;
                        
    if (wt[w]  <  wt[min])
                            min
    = w;
                    }

                }

            }

        }

    }

        
    namespace  DijkstraNS {  
    /* 解决:非负权图单源最短路径树SPT
     *算法:Dijkstra——O(V^2)
     *输入:加权连通图(矩阵):g
     *输出:父节点st[],与其父之边的权重wt[]
     
    */

        GraphMatrix
    < double >  g;
        
    int  st[maxV];    
        
    double  wt[maxV + 1 ];    
        
    int  fr[maxV];     // 非树顶点的最近树顶点
         void  spt( int  s) {
            
    int  v, w, min;
            
    for (v = 0 ; v < g.v;  ++ v) {
                st[v]
    =- 1 ; fr[v] = v; wt[v] = Inf;
            }

            st[s]
    = s; wt[g.v] = Inf; wt[s] = 0 ;
            
    for (min = s; min != g.v;) {
                v
    = min; st[v] = fr[v];
                
    for (w = 0 , min = g.v; w < g.v;  ++ w) {
                    
    if (st[w] ==- 1 ) {
                        
    if (g.a[v][w] != Inf  &&  wt[v] + g.a[v][w]  <  wt[w])
                            wt[w]
    = wt[v] + g.a[v][w], fr[w] = v;
                        
    if (wt[w]  <  wt[min])
                            min
    = w;
                    }

                }

            }

        }

    }

    /**/
    namespace  FloydNS { //   
    /* 解决:所有点对最短路径
     *算法:Floyd——O(V^3)
     *输入:加权连通图(矩阵):g
     *输出:最短距离长度矩阵d[][], 路径矩阵p[][]
     
    */

        GraphMatrix
    < double >  g;
        
    double  d[maxV][maxV];     // 最短路径长度
         int  p[maxV][maxV];         // 最短路径下一顶点
         void  floyd() {
            
    int  i,s,t;
            
    for (s = 0 ; s < g.v;  ++ s) {
                
    for (t = 0 ; t < g.v;  ++ t)
                    
    if ( (d[s][t]  =  g.a[s][t])  <  Inf)
                        p[s][t]
    = t;
                d[s][s]
    = 0 ;
            }

            
    for (i = 0 ; i < g.v;  ++ i)
                
    for (s = 0 ; s < g.v;  ++ s)
                    
    if (s != &&  d[s][i]  <  Inf)
                        
    for (t = 0 ; t < g.v;  ++ t)
                            
    if (d[s][t]  >  d[s][i]  +  d[i][t]) {
                                d[s][t] 
    =  d[s][i]  +  d[i][t];
                                p[s][t] 
    =  p[s][i];
                            }

        }

    }

    namespace  TenshiNS { //
    /* 解决:二分图最大匹配
     *算法:匈牙利匹配(by Tenshi)——O(xv * yv)
     *输入:邻接矩阵g
     *输出:匹配数cnt,x匹配项xm[],y匹配项ym[]
     *备注:from Bug 06-07-07
     
    */

        
    int  xv,yv;     // 顶点数
         int  g[maxV][maxV];     // g[i][j]=1 表示 xi与yj相邻
         int  sy[maxV];     // 辅助:当轮被搜过的y点都是1 
         int  cnt,xm[maxV],ym[maxV];  // 输出 
         void  init() {
            cnt
    = 0 ;
            memset(g,
    0 , sizeof (g));
            memset(xm,
    - 1 , sizeof (xm));
            memset(ym,
    - 1 , sizeof (ym));
        }

        
    bool  _path( int  u) // 返回是否找到增广路
         {
            
    for ( int  v = 0 ;v < yv;v ++ if (g[u][v]  &&   ! sy[v]) { sy[v] = 1 ;
                
    if (ym[v] ==- 1   ||  _path(ym[v]))  { xm[u] = v; ym[v] = u;  return   1 ;}
            }
      return   0 ;    
        }

        
    void  tenshi()
        
    {
            
    int  i;
            
    for (i = 0 ;i < xv;i ++ )
                
    if (xm[i] ==- 1 ) {
                    memset(sy,
    0 , sizeof (sy));
                    cnt
    += _path(i);
                }

        }
     
    }


        来源:

声明:本文由网友推荐或作者提交,版权归原作者所有,刊登此文仅为传播知识,展示研究成果,提高文章引用率。未经原作者授权,禁止用于任何形式的商业行为。科技论文网倡导尊重知识、尊重劳动、保护原创、知识共享。由于部分论文文章来于网络,文章作者不祥,请相关的原创作者与我们联系,以便加上您的署名。

  
经典的图论算法C++描述
下面没有链接了     常用算法—贪婪法
最新论文
·[程序设计]经典的图论算法C++描述
·[程序设计]常用算法—贪婪法
·[程序设计]20世纪10个最伟大的算法
·[程序设计]任意阶奇数幻方C程序
·[程序设计]二叉查找树示例
·[程序设计]朴素(Naive)字符串匹配算法
·[程序设计]平衡二叉树源码