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;
    }
};
posted @ 2024-04-17 10:51  pengge666  阅读(2)  评论(0编辑  收藏  举报