2316. 统计无向图中无法互相到达点对数

问题:

目前没有很好的方案去存储, 每个可以互通的无向图

思路:

1.先构建图关系数组

2.使用dfs深度优先搜索,找出每个节点的相邻节点

3.根据遍历前后的结果,计算当前无向图相对其它无向图的无法到达对数

Note:

由于在C++中,函数传递,默认是按值传递的,所以当在函数中传入较大的 数据时。例如这里的diagramVec,会导致超时,如下面这个函数,最后一个参数是按值传递,不会发生严重的拷贝问题

void dfs(int ind, long long *totalCount, vector<bool> &visitVec, vector<vector<int>> diagramVec);

修改成下面这样就不会发生拷贝问题了:

void dfs(int ind, long long *totalCount, vector<bool> &visitVec, vector<vector<int>> &diagramVec);

void dfs(int ind, long long *totalCount, vector<bool> &visitVec, vector<vector<int>> *diagramVec);

class Solution {
public:
    long long countPairs(int n, vector<vector<int>>& edges) {
      // 构建图
      vector<vector<int>> diagramVec(n);

      for(auto &vec : edges){
        int edge1 = vec[0];
        int edge2 = vec[1];

        diagramVec[edge1].push_back(edge2);
        diagramVec[edge2].push_back(edge1);
      }

      long long ans = 0LL;
      long long totalCount = 0;
      vector<bool> visitVec(n, false);

      // 使用lambda表达式,替换本地函数,加快处理速度
      // function<void(int)> dfs = [&](int ind){
      //   // 记录已经访问过这个节点
      //   visitVec[ind] = true;
      
      //   // 节点总数加一
      //   totalCount++;

      //   // 获取ind对应的相邻节点列表
      //   vector<int> &vec = diagramVec[ind];

      //   // 递归遍历其它相邻的节点
      //   for(auto index : vec){
      //     // 没有被访问则继续递归访问
      //     if(!visitVec[index]){
      //       dfs(index);
      //     }
      //   }
      // };

      // 遍历图计算        
      for(int ind = 0; ind < n; ind++){
        if(!visitVec[ind]){
          // 保存当前已经记录的节点总数
          long long totalCountPrev = totalCount;

          // 遍历与当前节点相连的每个节点
          // dfs(ind);
          dfs(ind, &totalCount, visitVec, diagramVec);

          // 本次相邻节点的的无法到达对数 = 上一次节点总数 * 本次相邻总数
          // 累加即为最后的答案
          ans += (totalCountPrev * (totalCount - totalCountPrev));
        }
      }

      return ans;
    }

    /*
      执行速度相对lambda慢80ms
     */
    void dfs(int ind, long long *totalCount, vector<bool> &visitVec, vector<vector<int>> &diagramVec){
      // 记录已经访问过这个节点
      visitVec[ind] = true;
      
      // 节点总数加一
      (*totalCount)++;

      // 获取ind对应的相邻节点列表
      vector<int> vec = diagramVec[ind];

      // 递归遍历其它相邻的节点
      for(auto index : vec){
        // 没有被访问则继续递归访问
        if(!visitVec[index]){
          dfs(index, totalCount, visitVec, diagramVec);
        }
      }
    }    
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值