问题:
目前没有很好的方案去存储, 每个可以互通的无向图
思路:
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);
}
}
}
};