5098:[BZOJ1098] [POI2007]オフィスBIU

5098:[BZOJ1098] [POI2007]オフィスBIU

素晴らしいの構造上のデータはありません

非常に形而上学に見えるコード

const int N=1e5+10,M=2e6+10;
  
int n,m;
int fa[N];
int Find(int x){ return fa[x]==x?x:fa[x]=Find(fa[x]); }
  
vector <int> G[N];
typedef vector <int> ::iterator iter;
  
  
void merge(int x,int y){
    x=Find(x),y=Find(y);
    if(x==y) return;
    vector <int> tmp;tmp.clear();
    if(G[x].size()>G[y].size()) swap(x,y);
    int p=0;
    for(reg int i=0;i<(int)G[x].size();i++){
        while(p<(int)G[y].size()&&G[y][p]<G[x][i]) p++;
        if(p>=(int)G[y].size()||G[y][p]!=G[x][i]) {
            tmp.push_back(G[x][i]);
            G[x].erase(G[x].begin()+i);
            i--;
        } 
    }
    fa[y]=x;
    rep(i,0,tmp.size()-1) merge(x,tmp[i]);
}
  
int cnt[N];
int ans[N],ac;
bool go[N];
  
  
  
void Sort(vector <int> &V){
    if(V.size()<20000) return sort(V.begin(),V.end());
    memset(go,0,sizeof go);
    rep(i,0,V.size()) go[V[i]]=true;
    V.clear();
    rep(i,1,n) if(go[i]) V.push_back(i);
}
 
int num[N]; 
 
bool cmp(int x,int y){
    return G[x].size()<G[y].size();
}
  
int main(){
    n=rd(),m=rd();
    rep(i,1,n) fa[i]=num[i]=i;
    rep(i,1,m) {
        int u=rd(),v=rd();
        G[u].push_back(v);
        G[v].push_back(u);
    }
    rep(i,1,n) Sort(G[i]);
    sort(num+1,num+n+1,cmp);
    rep(i,1,n) if(Find(num[i])==num[i]) {
        memset(go,0,sizeof go);
        rep(j,0,G[num[i]].size()-1) go[G[num[i]][j]]=1;
        rep(j,1,n) if(num[i]!=j&&!go[j]) merge(num[i],j);
    }
    rep(i,1,n) cnt[Find(i)]++;
    rep(i,1,n) if(cnt[i]) ans[++ac]=cnt[i];
    sort(ans+1,ans+ac+1);
    printf("%d\n",ac);
    rep(i,1,ac) printf("%d",ans[i]),putchar(i==ac?'\n':' ');
}
  

私はこれについて、このようなコードを話していました。

エッジ点に接続されていない、注文の度合いに応じて統合され、最終的にはセット数を見つけなければなりません

yが再び実行しないようにしかし、時間の合併は、yの答えでXを更新するために注意を払います(ここでは全体的な複雑さは、より奇妙です)

更新プロセス:このエッジは、x、それは省略され、この結合点でない場合、X、Yエッジのエッジを横切ります


まず、原理を分類整理に基づいて、最大の最小点がなければならない(\ \ FRAC {M} { N} \)

また、エッジの数である\(\ FRAC {M} { N} \)

互いに点をマージ、この複雑である(\ {N-FRAC {M}} \ CDOT Mが\)\(実際に!毎回ため辺の多数省略ランよりもはるかに少ないです!)

だから、Tものではありません

それ以来、合併の完了後よりも小さい必要があります\(\ FRAC {M} { N}を\) 点、そうもできた場合暴力ここで\(O(N)\)合併は問題ではありません

最後に、恐れ、\(\ FRAC {M} { N} \ CDOT M \)をTLEます

ルック凝視するとき\(M = 2E6、N \は ) Tに小さいです

あなたは小さなn個の実行指示し\を(O(N ^ 2) \) 望んでいません

そう自然に心配しないで、時間制限は、単に不満を実行し、このコードは20代であることに注意してください!

ヒント:ベクトルの最適化は、リストをさらに良くすることができ

おすすめ

転載: www.cnblogs.com/chasedeath/p/11258765.html