图(连通网络的操作次数etc)

这篇博客介绍了如何利用深度优先搜索(DFS)和并查集解决LeetCode上的1319题,即计算使所有计算机在给定网络中连通所需的最少操作次数。首先解释了连通网络的概念,然后详细阐述了深度优先搜索的实现,接着讲解了并查集的数据结构及其在找出图中连通分量数中的应用。最后提到了在深度神经网络模型执行时间最短的情况下的策略。
摘要由CSDN通过智能技术生成

1319. 连通网络的操作次数

用以太网线缆将 n 台计算机连接成一个网络,计算机的编号从 0 到 n-1。线缆用 connections 表示,其中 connections[i] = [a, b] 连接了计算机 a 和 b。
网络中的任何一台计算机都可以通过网络直接或者间接访问同一个网络中其他任意一台计算机。
给你这个计算机网络的初始布线 connections,你可以拔开任意两台直连计算机之间的线缆,并用它连接一对未直连的计算机。请你计算并返回使所有计算机都连通所需的最少操作次数。如果不可能,则返回 -1 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-operations-to-make-network-connected

深度优先搜索
初始时所有节点都为待搜索状态,每次选择一个待搜索的节点,从该节点开始进行深度优先搜索,并将所有搜索到的节点的状态更改为「已搜索」,这样我们就找到了一个连通分量。

const dfs = function(u, used, edges) {
    used[u] = 1;
    if (edges[u]) {
        for(let k of edges[u]) {
            used[k] === 0 ? dfs(k, used, edges) : null;
        }
    }
}
var makeConnected = function(n, connections) {
    if(n - connections.length > 1) return -1;
    let edges = {};
    for(let [a,b] of connections) {
        edges[a] ? edges[a].push(b) : edges[a] = [b];
        edges[b] ? edges[b].push(a) : edges[b] = [a];
    }
    console.log(edges)
    let used = Array(n).fill(0);
    let ans = 0;
    for(let i = 0;i < used.length; i++) {
        console.log(used[i])
        if (used[i] === 0) {
            dfs(i, used, edges);
            ans++;
        }
    }
    return ans-1;
};

并查集:
我们可以使用并查集来得到图中的连通分量数。并查集本身就是用来维护连通性的数据结构。如果其包含 n 个节点,那么初始时连通分量数为 n,每成功进行一次合并操作,连通分量数就会减少1。

var makeConnected = function(n, connections) {
    if (connections.length < n - 1) {
        return -1;
    }

    const uf = new UnionFind(n);
    for (const conn of connections) {
        uf.unite(conn[0], conn[1]);
    }

    return uf.setCount - 1;
};

更简便的写法,在此题中

const find = function(k, parent) {
    while(parent[k] !== -1) {
        k = parent[k];
    }
    return k;
}
var makeConnected = function(n, connections) {
    if(n - connections.length > 1) return -1;
    let parent = Array(n).fill(-1);
    // path记录的值是在遍历过程中连接的独立的关系数
    let path = Array(n).fill(0);
    for(let [x,y] of connections) {
        x = find(x, parent);
        y = find(y, parent);
        if(x != y){
        	// 谁连接的独立关系多就将小的那个节点指向大的,相等则指向y【后一个】并将path[y]+1
            if(path[x] > path[y]){
                parent[y] = x;
            }else if(path[x] < path[y]){
                parent[x] = y;
            }else{
                parent[x] = y;
                path[y]++;
            }
        }
    }
    let count = -1;
    // -1个数就代表独立节点关系个数,其余值表示指向的节点下标
    for(let i of parent) {
        i === -1 ? count++ : null;
    }
    return count;
};

并查集模板

// 并查集模板
class UnionFind {
    constructor (n) {
        this.parent = new Array(n).fill(0).map((element, index) => index);
        this.size = new Array(n).fill(1);
        // 当前连通分量数目
        this.setCount = n;
    }

    findset (x) {
        if (this.parent[x] === x) {
            return x;
        }
        this.parent[x] = this.findset(this.parent[x]);
        return this.parent[x];
    }

    unite (a, b) {
        let x = this.findset(a), y = this.findset(b);
        if (x === y) {
            return false;
        }
        if (this.size[x] < this.size[y]) {
            [x, y] = [y, x];
        }
        this.parent[y] = x;
        this.size[x] += this.size[y];
        this.setCount -= 1;
        return true;
    }

    connected (a, b) {
        const x = this.findset(a), y = this.findset(b);
        return x === y;
    }
}

深度神经网络模型执行的最短时间

采用深度遍历法, 最小执行时间但是得执行完整个网络,那么就是每一个深度执行时间的最大值。

// 输出为网络模型的最小执行时间
var shortTime = function(arr) {
    function fn (arr, index) {
        let time = 0;
        let head = arr[index];
        let count = 0;
        while(count < head.length) {
            count++;
            let temp = head[0];
            temp += (head[count] ? fn(arr, head[count]) : 0);
            console.log(temp, time);
            time = Math.max(temp, time);
        }
        return time;
    }
    return fn(arr, 0)
}
console.log(shortTime([[10, 1, 2],[5],[1,3],[2, 4],[5]]))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值