zoukankan      html  css  js  c++  java
  • 最小树形图

    关于最小树形图, 看了下资料和研究了一下代码 。

    熟悉了最小树形图的结构还有朱刘算法的大概过程。

    最小树形图 跟 最小生成树有两点不同之处: 一有向 、二有根 。

    简而言之 , 是能够从根到达各个节点 , 所构成的有向图 , 要求边权之和最小 。

    对于朱刘算法 ,有4个步骤 。

    1.判断是否存在最小树形图 。

    2.对图进行标记,判环,无环则可返回。

    2.将图中的环缩成点。

    3.构成新图。

    对于标记缩点的时候 ,朝着pre[u]走要么就是回溯到root , 要么就是构成了环。

    在构新图的时候 , 若然e[i].u , e[i].v在环里 , 可以直接扔掉 , 因为在操作2的时候,整个环的权值已经加过了 。

    当有点进入环的时候 , 比如进入环中一点 v , 其权要减回一个in[v] ( 表示上一次构图指向v的边的最小权 , 在上一次步骤2的时候多加到了结果中 )。

    double zhuliu( int root ) {
        double res = 0 ; int u , v ;
        while(1) {
            for( int i = 0 ; i < n ; ++i ) in[i] = inf ;
    
            for( int i = 0 ; i < m ; ++i )
                if( e[i].u != e[i].v && e[i].w < in[e[i].v] ) {
                    pre[e[i].v] = e[i].u;
                    in[e[i].v] = e[i].w;
                }
            for( int i = 0 ; i < n ; ++i )
                if( i != root && in[i] == inf )
                    return -1 ;
            int tn = 0 ;
            memset( id , -1 , sizeof id );
            memset( vis , -1 , sizeof vis );
            in[root] = 0 ;
            for( int i = 0 ; i < n ; ++i ) {
                res += in[i];
                v = i ;
                while( vis[v] != i && id[v] == -1 && v != root ) {
                    vis[v] = i ;
                    v = pre[v] ;
                }
                if( v != root && id[v] == -1 ) {
                    for( int u = pre[v] ; u != v ; u = pre[u] )
                        id[u] = tn ;
                    id[v] = tn++ ;
                }
            }
            if( tn == 0 ) break ; // no circle
            for( int i = 0 ; i < n ; ++i ) if( id[i] == -1 ) {
                id[i] = tn++ ;
            }
            for( int i = 0 ; i < m ; ){
                v = e[i].v;
                e[i].u = id[e[i].u];
                e[i].v = id[e[i].v];
                if( e[i].u != e[i].v )
                    e[i++].w -= in[v];
                else
                    swap( e[i] , e[--m] );
            }
            n = tn ;
            root = id[root];
        }
        return res ;
    }
    View Code
    only strive for your goal , can you make your dream come true ?
  • 相关阅读:
    Ubuntu18.04 一些好用的扩展
    Java并发编程:volatile关键字解析
    SpringCloud(0) 外行人都能看懂的SpringCloud,错过了血亏!
    Java8中的流操作-基本使用&性能测试
    JDBC基本操作
    单例模式(二)
    单例模式(一)static、final和单例模式
    Lombok的使用与原理
    Linux下出现permission denied的解决办法
    虚拟机安装
  • 原文地址:https://www.cnblogs.com/hlmark/p/4292078.html
Copyright © 2011-2022 走看看