代码拉取完成,页面将自动刷新
//
// Created by 高森森 on 2022/2/13.
//
#ifndef LEETCODE_SOLUTION41_H
#define LEETCODE_SOLUTION41_H
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include <numeric>
#include "Solution40.h"
using namespace std;
/*class UnionFind2{
public:
vector<int>father;//父亲节点
int n;//节点个数
vector<int>size;//连通分量数
vector<int>rank;
public:
//查询父结点
UnionFind2(int _n):n(_n),father(_n),size(_n,1),rank(_n,1){
//iota函数,令father[i]=i;
iota(father.begin(),father.end(),0);
}
int find(int x){
if(x==father[x])
return x;
else{
father[x]=find(father[x]);
return father[x];
}
}
//并查集合并
void merge(int i,int j){
int x=find(i);
int y=find(j);
if(x!=y){
if(rank[x]<rank[y]){
swap(x,y);
father[y]=x;
size[x]+=size[y];
if (rank[x] == rank[y])
rank[x] += 1;
}
}
}
bool isConnected(int x,int y){
x=find(x);
y=find(y);
return x==y;
}
};*/
class Solution41 {
public:
int minMalwareSpread(vector<vector<int>>& graph, vector<int>& initial) {
//使用dfs计算每个感染源节点可以感染的正常节点个数
//然后统计每个正常节点可以被哪些感染源节点感染
//如果正常节点可以被多个感染源感染,那么删除其中一个感染源是无用的,因为该正常节点
//还会被其他感染源节点感染,不会影响M的导小
//最后统计一下只被一个感染源感染的正常节点中,感染源节点分别感染了哪些正常节点,取得最大轴
int n=graph.size();
vector<int>infectSorce(n);
sort(initial.begin(),initial.end());
for(int node:initial){
infectSorce[node]=1;
}
//记录正常节点可以被哪些感染源感染
vector<vector<int>>infectedBy(n);
for(int n:initial){
set<int>infected;
dfs(graph,infectSorce,infected,n);
for(int v:infected){
infectedBy[v].push_back(n);
}
}
//统计只被一个感染源节点感染的正常节点中,感染源节点可以感染的节点个数
vector<int>count(n,-1);
for(auto c:infectedBy){
if(c.size()==1)
count[c[0]]++;
}
int min=-1;
int ans=initial[0];
for(int i=0;i<n;i++)
{
if(count[i]>min){
ans=i;
min=count[i];
}
}
return ans;
}
void dfs(vector<vector<int>>&graph,vector<int>&infectSorce,set<int>&infected,int u){
for(int j=0;j<graph.size();j++){
if(graph[u][j]==1&&infectSorce[j]==0&&!infected.count(j))
{
infected.insert(j);
dfs(graph,infectSorce,infected,j);
}
}
}
int minMalwareSpread2(vector<vector<int>>& graph, vector<int>& initial) {
int n=graph.size();
sort(initial.begin(),initial.end());
int max=-1;
int ans=initial[0];
UnionFind2 unionFind2(n);
//对于所有的正常集合构建并查集
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++){
if(!count(initial.begin(),initial.end(),i)&&!count(initial.begin(),initial.end(),j))
{
if(graph[i][j]==1)
unionFind2.merge(i,j);
}
}
//infectRoot:记录感染源的个数
//主要记录连通分量的感染来源个数,只有连通分量的根节点存在值,其他下表为-1
//如果下标-1 说明不是连通分量分界点
//如果是-2 说明多个感染源
//其他值说明该连通分量的单一感染源
vector<int>infectRoot(n,-1);
for( int i:initial){
for(int j=0;j<n;j++)
{
if(count(initial.begin(),initial.end(),j))
continue;
int fa=unionFind2.find(j);
if(infectRoot[j]==-2||graph[i][j]==0)
continue;
if(infectRoot[fa]==-1){
infectRoot[fa]=i;
}
//如果这个连通分量存在感染源,并且不是i,说明有多个感染源
else if(infectRoot[fa]!=i){
infectRoot[fa]==-2;
}
}
}
vector<int>infectNum(n,0);
for(int i=0;i<n;i++){
if(infectRoot[i]==-1||infectRoot[i]==-2)
continue;
infectNum[infectRoot[i]]+=unionFind2.size[i];
}
for(int i:initial){
if(infectNum[i]>max)
{
max=infectNum[i];
ans=i;
}
}
return ans;
}
};
#endif //LEETCODE_SOLUTION41_H
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。