朱刘算法(最小树形图)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Game_Acm/article/details/82382022

复杂度O(n*m)

struct edge
{
    int u,v,cost;
}es[maxm];
int pre[maxn],id[maxn],vis[maxn],in[maxn],n,m;
int ZhuLiu( int root )
{
    int res = 0;
    while ( true )
    {
        for ( int i=0 ; i<n ; i++ ) in[i] = inf;
        for ( int i=0 ; i<m ; i++ )
        {
            int u = es[i].u,v = es[i].v,w = es[i].cost;
            if ( u!=v&&w<in[v] ) in[v] = w,pre[v] = u;
        }
        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];
            int v = i;
            while ( vis[v]!=i&&id[v]==-1&&v!=root )
                vis[v] = i,v = pre[v];
            if ( id[v]==-1&&v!=root )
            {
                for ( int u=pre[v] ; u!=v ; u=pre[u] )
                    id[u] = tn;
                id[v] = tn++;
            }
        }
        if ( tn==0 ) break;
        for ( int i=0 ; i<n ; i++ )
            if ( id[i]==-1 ) id[i] = tn++;
        for ( int i=0 ; i<m ; i++ )
        {
            int v = es[i].v;
            es[i].u = id[es[i].u];
            es[i].v = id[es[i].v];
            if ( es[i].u!=es[i].v )
                es[i].cost -= in[v];
        }
        n = tn,root = id[root];
    }
    return res;
}

猜你喜欢

转载自blog.csdn.net/Game_Acm/article/details/82382022
今日推荐