928. 尽量减少恶意软件的传播 II【并查集加暴力删边判断】
题意不是很清晰:
1.比如对于 graph=[[1,1,0],[1,1,1],[0,1,1]], initial=[0,1] 来说,可以发现结点的链接情况是 0-1-2,感染源结点是0和1,若是按之前题目的要求,移除0和1都不会减少最终感染个数,但是应该返回结点0,因为其 index 小。但是应用此题的条件,就一定要返回结点1,因为移除结点1之后,就断开了结点0和结点2的连接,最终只有病毒源结点0会保持感染状态,这就是二者的区别所在。
2.返回索引 最小的节点,有点坑,具体看代码。
这道题目就是纯纯的大模拟题。好久没写大模拟了。
const int N = 2e4+100 ;
const int inf =0x3f3f3f3f;
class Solution {
public:
int f[N];
set<int> s[N];
map<int,int> mp;
map<int,int> vis;
vector<int> g[N];
int getf(int v){
if(v==f[v]){
return f[v];
}
f[v]=getf(f[v]);
return f[v];
}
void merge(int a,int b){
int t1=getf(a);
int t2=getf(b);
if(t1!=t2){
f[t2]=t1;
}
}
int minMalwareSpread(vector<vector<int>>& graph, vector<int>& initial) {
int n=graph.size();
mp.clear();
for(int i=0;i<=n;i++){
f[i]=i;
g[i].clear();
}
for(auto &num:initial) vis[num]=1;
for(int i=0;i<n;i++) s[i].clear();
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(j==i) continue;
if(graph[i][j]) {
merge(i,j);
g[i].push_back(j);
g[j].push_back(i);
}
}
}
int mx=0;
for(int i=0;i<n;i++){
s[getf(i)].insert(i);
mx=max(mx,getf(i));
}
int sum=0;// 计算总的感染的个数
int maxx=0;
int idx=-1;
for(int i=0;i<=mx;i++){
if(s[i].empty()) continue;
int flag=false;
for(int j=0;j<initial.size();j++){
if(s[i].find(initial[j])!=s[i].end()){
flag=true;
mp[initial[j]]=i;
// break;
}
}
if(flag){
sum=sum+s[i].size();
}
}
// cout<<"debug 并查集 st"<<endl;
// for(int i=0;i<=mx;i++){
// cout<<"并查集的i:"<<i<<endl;
// for(auto si:s[i]) cout<<si<<" ";
// cout<<endl;
// }
// cout<<"debug 并查集 ed"<<endl;
// 遍历每个删除的initial
for(int i=0;i<initial.size();i++){
int num=initial[i];
int place=mp[num];
queue<int> q;
while(q.size()) q.pop();
// cout<<"deubug Queue start"<<endl;
for(auto si:s[place]){
if(vis[si]&&si!=num){
cout<<si<<" ";
q.push(si);
}
}
cout<<endl;
// cout<<"debug Queue end"<<endl;
map<int,int> mmp;
mmp.clear();
int tot=0;
// cout<<"debug process start"<<endl;
while(q.size()){
auto cur=q.front();
q.pop();
if(mmp[cur]) continue;
mmp[cur]=1;
cout<<cur<<" ";
tot++;
for(int i=0;i<g[cur].size();i++){
int to=g[cur][i];
if(to==num||cur==num){
continue;
}else{
q.push(to);
}
}
}
// cout<<"\ndebug process end"<<endl;
// cout<<i<<" "<<tot<<" "<<maxx<<" "<<num<<endl;
int res=s[place].size()-tot;
if(res>=maxx){
if(res>maxx||idx==-1){
idx=num;
}
else{
idx=min(idx,num);
}
maxx=res;
}
}
return idx;
}
};