提示:
1.题解:(来自力扣官方题解)
1.方法一:枚举每一个连通分量
我们可以分别考虑每一个连通分量:
如果其中没有感染节点,那么无需考虑;
如果其中恰好有一个感染节点,移除该节点可以使得最终感染的节点数减少,减少的值即为该连通分量的大小;
如果其中有超过一个感染节点,那么无论移除哪一个节点,剩下的那个(那些)节点总会感染连通分量中的所有节点,同样无需考虑。
因此,我们可以首先使用深度优先搜索 / 广度优先搜索 / 并查集的方法求解出所有的连通分量,需要记录的值为:
每一个节点所在的连通分量的编号,以及每一个连通分量的大小。
class Solution {
public:
int minMalwareSpread(vector<vector<int>>& graph, vector<int>& initial) {
int n = graph.size();
vector<int> ids(n);
unordered_map<int, int> id_to_size;
int id = 0;
for (int i = 0; i < n; ++i) {
if (!ids[i]) {
++id;
int size = 1;
queue<int> q;
q.push(i);
ids[i] = id;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int v = 0; v < n; ++v) {
if (!ids[v] && graph[u][v] == 1) {
++size;
q.push(v);
ids[v] = id;
}
}
}
id_to_size[id] = size;
}
}
unordered_map<int, int> id_to_initials;
for (int u: initial) {
++id_to_initials[ids[u]];
}
int ans = n + 1, ans_removed = 0;
for (int u: initial) {
int removed = (id_to_initials[ids[u]] == 1 ? id_to_size[ids[u]] : 0);
if (removed > ans_removed || (removed == ans_removed && u < ans)) {
ans = u;
ans_removed = removed;
}
}
return ans;
}
};