这种涉及不同连通分量的,看上去就可以用并查集。并查集的模板请参见上一篇内容。并查集(力扣1971)-优快云博客
现在我们要求的是无法互相到达的点对。根据观察易得,我们只需要求出每个并查集的元素数量,然后遍历每个点,设它所在的并查集元素数量为size,那么它所不能到达的点的数量就为n-size.最后除2即可。
class Solution
{
public:
int find(vector<int>& father, int u)
{
return u == father[u] ? u : father[u] = find(father, father[u]);
}
void join(vector<int>& father, int u, int v)
{
u = find(father, u);
v = find(father, v);
if (u == v) return;
father[v] = u;
}
long long countPairs(int n, vector<vector<int>>& edges)
{
vector<int>father(n);
for (int i = 0; i < n; i++)//并查集初始化
{
father[i] = i;
}
unordered_map<int, int>mp;//mp.first:并查集的根值 mp.second:集合中元素的数量
for (auto p : edges)
{
join(father,p[0], p[1]);
}
for (int i = 0; i < n; i++)
{
int root = find(father, i);//找到节点i的根值
mp[root]++;//mp[root]:以root为根的并查集的元素数量
}
long long ans = 0;
//查询每一个点,看它所在的并查集中的元素的数量,设为size,则n-size是它不能访问到的节点的数量
for (int i = 0; i < n; i++)
{
int root = find(father, i);//找到它的根节点
ans += (n - mp[root]);
}
return ans / 2;
}
};