leetcode 1319.连通网络的操作次数

思路:DFS(连通块)

其实一开始的时候,并不知道这道题的精髓在哪,总想着,啊?这怎么用图论的思想做啊?

细细思考之后,这道题还是比较有意思的,需要有一定的数据结构基础。

这里让我们求最少连接的操作次数。我们其实可以把这些点统统看成是连通块。

例如第一个例子,0,1,2是不是连在一块了?3是不是独立成一块?也就是说,这个例子里面,有两个连通块。我们需要用几条线来连接?我们发现,只需要一条。也就说,2个连通块需要一条来连接,这样全部点都可以访问;如果是3个连通块呢?其实你已经能推出来了,就是2条。

其实这就跟树一样,n个顶点,至少需要n-1边才能成树(树也是图的一种)。这里就运用了这样的数据结构的基础知识。

好了,我们的任务其实就很明确了,找出有多少块连通块;然后,我们需要统计总共给了我们多少条线;最后,我们需要判断连通这些点的最小线数,然后判断一下题目中给我们的线够不够用。

第一个问题很好解决,dfs遍历,然后用一个全局变量统计就行,不要忘记每次dfs的时候需要更新这个变量;

第二个问题,极其的简单,就是connections的二维数组大小。

第三个问题,我们需要着重注意一下细节,首先,我们需要知道一个连通块最少需要多少条线,其实就是上面的知识点,n个顶点的话n-1个就够了,就能至少形成一个连通块。这样的话,我们其实就是重新统计了一遍每个连通块所用的条数,然后相加到sum中,判断总条数-sum,就是我们能够最大限度用的线了。如果说,我们剩下的线足够我们连通这几个连通块,那么就取能够连通这几个连通块的最小条数,而不取剩下的条数;否则,就不能连接上。

注意:你需要额外定义一个二维数组存储各顶点的联通关系。

上代码:

class Solution {
public:
int counts=0;
void dfs(int u,vector<vector<int>>&s,vector<bool>&st){
    for(int i=0;i<s[u].size();i++){
        int tmp=s[u][i];
        if(!st[tmp]){
            st[tmp]=true;
            counts++;
            dfs(tmp,s,st);
        }
    }
}
    int makeConnected(int n, vector<vector<int>>& connections) {
        int res=0;
        vector<vector<int>>s(n);
        vector<bool>st(n,false);
        vector<int>ans;
        for(int i=0;i<connections.size();i++){
            int x=connections[i][0];
            int y=connections[i][1];
            s[x].emplace_back(y);
            s[y].emplace_back(x);
        }
        for(int i=0;i<n;i++){
            if(!st[i]){
                st[i]=1;
                res++;
                dfs(i,s,st);
            }
            ans.push_back(counts);
            counts=0;
        }
        int sum=0;
        for(int i=0;i<ans.size();i++){
            sum+=ans[i];
        }
        if(connections.size()>=sum)
            return connections.size()-sum>=res-1?res-1:-1;
        else
        return -1;
    }
};

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值