LeetCode 924 尽量减少恶意软件的传播
本题是给出一个图,标注有哪些节点相连接,这些节点中有若干个感染病毒,并且相连接的节点其中如果有一个感染,它就会把病毒传染给它所连接的节点,问从初始感染列表中去掉哪一个节点可使最终感染的节点数最小,如果有多个节点满足条件,输出标号最小的节点。这道题思路就是首先求出有多少个连通的区域,一个区域内有一个感染的节点,最终整个区域中所有的节点都会被感染。记录这些区域中的节点数,初始状态下,如果一个区域没有感染的节点可以不考虑这个区域,如果一个区域有两个及以上感染的结点,那么无论删去哪一个这个区域就还是会处于感染状态,如果一个区域只有一个感染的节点,那么去掉这个节点就会使整个区域没有感染发生。优先去找区域内只有一个感染节点的区域,选择区域内节点最多的区域,那么答案就是一个区域内节点最多且只有一个感染节点的那个感染节点,如果有多个区域满足条件,就比较感染节点的标号,选择最小的,如果没有只有一个感染节点的区域,返回所有感染节点的最小标号即可。
class Solution {
public:
int vis[305],cnt[305],first[305],belong[305];
vector<int> v[305];
int minMalwareSpread(vector<vector<int>>& graph, vector<int>& initial) {
int n=graph.size();
int all=0;
for(int i=0;i<n;i++)
if(!vis[i])
{
int kcnt=0;
queue<int> q;
vis[i]=1;
q.push(i);
first[all]=i;
belong[i]=all;
while(!q.empty())
{
kcnt++;
int u=q.front();q.pop();
for(int j=0;j<n;j++)
{
if(vis[j]||graph[u][j]==0) continue;
vis[j]=1;
belong[j]=all;
q.push(j);
}
}
cnt[all]=kcnt;
all++;
}
sort(initial.begin(),initial.end());
for(int i=0;i<initial.size();i++)
{
for(int j=0;j<all;j++)
if(belong[initial[i]]==belong[first[j]])
{
v[j].push_back(initial[i]);break;
}
}
int ans=999,maxnode=-1;
for(int i=0;i<all;i++)
{
int sz=v[i].size();
if(sz==1)
{
if(maxnode<cnt[i]||(maxnode==cnt[i]&&ans>v[i][0]))
{
maxnode=cnt[i];
ans=v[i][0];
}
}
else if(sz>1&&maxnode==-1)
{
ans=min(ans,v[i][0]);
}
}
return ans;
}
};