码迷,mamicode.com
首页 > 其他好文 > 详细

最小树形图

时间:2015-02-14 19:57:48      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:

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

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

 

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

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

 

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

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

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

2.将图中的环缩成点。

3.构成新图。

 

 

技术分享
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

 

最小树形图

标签:

原文地址:http://www.cnblogs.com/hlmark/p/4292078.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!