读题读一年,题是个水题
题目描述
原地址
大致意思是给你一个图,然后一开始其中的一些点有传染性,跟其在同一联通块的点全部会被传染。我们把一开始有传染性的点的集合称之为 initial,然后在一开始的时候,你可以在 initial 里面选一个,让这个点变得没有传染性。现在问你选择哪个点可以使得被传染的点最少。
题解
其实很显然,当一个联通块里的点只有一个点在 initial 里面的时候,整个联通块就会避免被感染,然后这题的解法就是找一个符合条件且最大的联通块就行了。
代码
因为一开始尝试着写了写,结果弄的是一个要用好多遍 bfs 的做法,实际上只要 bfs 一次就好了。
class Solution {
public:
int minMalwareSpread(vector<vector<int>>& graph, vector<int>& initial) {
const int N = graph.size();
sort (initial.begin(), initial.end()); // 因为序号更小的点优先级更高,所以排序
vector<int> vis(N, 0); // 记录被感染的点
function<int(int)>bfs = [&](int x){
for (int i = 0; i < N; i++) // 记得 init
vis[i] = 0;
queue<int> q;
for (int i = 0; i < initial.size(); i++) // 把 initial 全部都搞进去,除了被枚举要去除传染性的点
if (initial[i] != x)
q.push(initial[i]), vis[initial[i]] = 1;
while (!q.empty()) // 把相连的点标记一下
{
int u = q.front();
q.pop();
for (int i = 0 ; i < N; i++)
{
if (graph[u][i] == 0 || vis[i] == 1)
continue;
q.push(i), vis[i] = 1;
}
}
int cnt = 0;
for (int i = 0; i < N; i++) // 对没被感染的点进行计数
if (!vis[i])
cnt++;
return cnt;
};
int ans_node = -1, ans_cnt = -1;
for (int i = 0; i < initial.size(); i++) // 看看哪个点更优
{
int cnt = bfs(initial[i]);
if (cnt > ans_cnt)
ans_node = initial[i], ans_cnt = cnt;
}
return ans_node;
}
};
结果

有点丑陋,但是反正是过了
作者能力有限,如果有任何错误之处,还请各位指教。(~ ̄▽ ̄)~
博客围绕LeetCode一道图传染问题展开。题目是给定图,部分点有传染性,同一联通块会被传染,可在初始有传染性点集中选一个使其无传染性,求选哪个点可使被传染点最少。题解是找符合条件且最大的联通块,代码最初用多次bfs,实际一次即可,最终通过。

被折叠的 条评论
为什么被折叠?



