连通两组点的最小成本

发布时间 2023-06-20 08:55:41作者: 失控D大白兔

如果两个组中的每个点都与另一组中的一个或多个点连接,则称这两组点是连通的
返回连通两组点所需的最小成本

1. 状态压缩 + 动态规划

class Solution {
public:
    int connectTwoGroups(vector<vector<int>>& cost) {
        //这里使用状态压缩记录连通状态,同时使用动态规划最优化
        int m = cost.size(); int n = cost[0].size();
        vector<vector<int>> dp(m+1,vector<int>(1<<n,INT_MAX/2));//dp[i][j]表示s1前i个点与j状态下的s2的最小连通成本
        dp[0][0] = 0;//初始成本为0 , 无法连通成本无穷大
        for(int i=1;i<=m;i++){ //遍历点集1
            //将新增点与集合2所有状态连通
            for(int mask=0;mask<(1<<n);mask++){ //遍历点集2的所有状态,递推计算对应状态下最小代价
                for(int k=0;k<n;k++){//处理对应状态的每一个点
                    if(mask&(1<<k)==0) continue; //对应点不在状态中,跳过
                    //尝试将新增点1与点2连通
                    dp[i][mask] = min(dp[i][mask], dp[i][mask^(1<<k)] + cost[i-1][k]);  //新增点1可能会连通集合2中其它点
                    dp[i][mask] = min(dp[i][mask], dp[i-1][mask] + cost[i-1][k]);   //新增点1重复连通点2 , 用于新增点的连通
                    dp[i][mask] = min(dp[i][mask], dp[i-1][mask^(1<<k)] + cost[i-1][k]);  //新增点1和点2仅连通彼此
                }
            }
        }
        return dp[m][(1<<n)-1]; //返回所有点连通的最小代价
    }
};