去除边后找到所有可能树的单个和

时间:2019-02-06 11:18:52

标签: c++ algorithm performance tree time-complexity

给定一棵具有N个节点且节点权重非零的树,该树中有多少棵树(除去一个或多个边缘)的权重之和为x(给定)?

例如:

N = 3,每个顶点的权重为1 1 1,x = 2

边缘

1 2

2 3

现在删除1-2,我们有2个树1和2-3,权重分别为1和2,我们删除了边2-3,我们有1-2和3,权重为2和1 因此,在所有可能的树中(除去一个或多个边缘后),总共有2棵树,权重之和等于2。

我的解决方案-:

我只能提出一种复杂度为2 ^ n(其中n可以大到10 ^ 5)的蛮力解决方案。

Brute Force-:切割每个边缘,并对所有形成的树应用bfs / dfs,并添加各自的顶点权重,并检查总和是否等于x。

我认为可以使用DP记忆来优化此功能,但是我无法提出重复关系。

我也尝试过最小切割算法,但据我所知,它在这里并不适用。

int bfs()
{
    for(each cut in 2^n using bitmask)
    {
        queue <int> q;
        q.push(s);
        vis[ s ] = true;
        while(!q.empty())
        {
            int p = q.front();
            q.pop();
            for(int i = 0;i < v[ p ].size() ; i++)
            {
                if(vis[ v[ p ][ i ] ] == false)
                {
                    sum+=w[p][i]; // weight of p-i edge is w[p][i]                  
                    q.push(v[ p ][ i ]);
                    vis[ v[ p ][ i ] ] = true;
                }
            }        
        }
    }
}

以上2 ^ n个解是否有更好的算法/优化方法,根据这个问题,可能有O(n)或O(n * logn)解。

如果有什么更好的方法可以建议,请提供;或者如果此处需要一些切树算法,请提出建议。

0 个答案:

没有答案