zoukankan      html  css  js  c++  java
  • 【思维】复杂度均摊+并查集——icpc cerc 2019 Saba1000kg

    /*
    复杂度均摊:
    如果M>sqrt(N),这种询问最多sqrt(N)组,直接把所有边扫一遍求联通块即可
    如果M<sqrt(N),直接两两枚举点判边,复杂度M^2,总复杂度N/M*M^2=NM 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define N 100005 
    
    vector<pair<int,int>>e;
    set<pair<int,int> >s;
    
    int n,E,P,a[N],F[N],id[N];
    int find(int x){
        return F[x]==x?x:F[x]=find(F[x]);
    }
    
    
    int main(){
        //freopen("140.in","r",stdin);
        cin>>n>>E>>P;
        for(int i=1;i<=E;i++){
            int u,v;scanf("%d%d",&u,&v);
            if(u>v)swap(u,v);
            e.push_back(make_pair(u,v));
            s.insert(make_pair(u,v));
        }
        while(P--){
            int m;scanf("%d",&m);
            for(int i=1;i<=m;i++)scanf("%d",&a[i]);
            sort(a+1,a+1+m);
            for(int i=1;i<=m;i++)F[i]=i,id[a[i]]=i;
            if(m<=sqrt(n)){
                for(int i=1;i<=m;i++)
                    for(int j=i+1;j<=m;j++)
                        if(s.find(make_pair(a[i],a[j]))!=s.end()){
                            int fu=find(i),fv=find(j);
                            if(fu!=fv)F[fu]=fv;
                        }
            }else {
                for(auto p:e)if(id[p.first] && id[p.second]){
                    int fu=find(id[p.first]),fv=find(id[p.second]);
                    if(fu!=fv)F[fu]=fv;
                }
            }
            int ans=0;
            for(int i=1;i<=m;i++)if(F[i]==i)ans++;
            for(int i=1;i<=m;i++)id[a[i]]=0;
            cout<<ans<<'
    ';
        }
    }
     
  • 相关阅读:
    CSS居中布局总结
    Jquery的普通事件和on的委托事件
    sass基础用法
    JS中常遇到的浏览器兼容问题和解决方法
    KVC
    关键字 self
    常见的出现内存循环引用的场景有哪些?
    XCODE中的蓝色文件夹与黄色文件夹
    oc 关键字
    uiwebview 兼容性
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12915538.html
Copyright © 2011-2022 走看看