zoukankan      html  css  js  c++  java
  • bzoj 1098

    对于关系,看其是否是“等价关系”,即满足:自反,传递,对称。

    如果是可以用并查集来连接等价类。

    这道题是求原图补集的联通快个数,考虑原图度最少的点(由鸽巢原理,最多为2*e/n个)。

    先将未与其连边的点并在一个集合中,然后再用剩下的点暴力,每次O(n),最多暴力O(2*e/n)次,所以总的复杂度是O(e)的。

     1 /**************************************************************
     2     Problem: 1098
     3     User: idy002
     4     Language: C++
     5     Result: Accepted
     6     Time:8932 ms
     7     Memory:31140 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <cstring>
    12 #include <vector>
    13 #include <algorithm>
    14 #define maxn 100010
    15 using namespace std;
    16  
    17 int n, m;
    18 int dgr[maxn];
    19 vector<int> g[maxn], stk;
    20 int fa[maxn], sz[maxn];
    21 bool mark[maxn];
    22  
    23  
    24 void init() {
    25     for( int i=1; i<=n; i++ ) fa[i]=i;
    26 }
    27 int find( int a ) {
    28     return a==fa[a] ? a : fa[a]=find(fa[a]);
    29 }
    30 void unon( int a, int b ) {
    31     fa[find(a)] = find(b);
    32 }
    33  
    34 int main() {
    35     scanf( "%d%d", &n, &m );
    36     for( int i=1,u,v; i<=m; i++ ) {
    37         scanf( "%d%d", &u, &v );
    38         g[u].push_back( v );
    39         g[v].push_back( u );
    40         dgr[u]++, dgr[v]++;
    41     }
    42     int mu=1;
    43     init();
    44     for( int u=2; u<=n; u++ ) if( dgr[u]<dgr[mu] ) mu=u;
    45  
    46     for( int t=0; t<g[mu].size(); t++ ) mark[g[mu][t]]=true;
    47     for( int u=1; u<=n; u++ ) if( !mark[u] ) unon(u,mu);
    48     for( int t=0; t<g[mu].size(); t++ ) mark[g[mu][t]]=false;
    49  
    50     for( int t=0; t<g[mu].size(); t++ ) stk.push_back( g[mu][t] );
    51     for( int i=0; i<stk.size(); i++ ) {
    52         int u=stk[i];
    53  
    54         for( int t=0; t<g[u].size(); t++ ) mark[g[u][t]] = true;
    55         for( int v=1; v<=n; v++ ) if( !mark[v] ) unon(u,v);
    56         for( int t=0; t<g[u].size(); t++ ) mark[g[u][t]] = false;
    57     }
    58     for( int u=1; u<=n; u++ )
    59         sz[find(u)]++;
    60     vector<int> ans;
    61     for( int u=1; u<=n; u++ )
    62         if( fa[u]==u ) ans.push_back(sz[u]);
    63     sort( ans.begin(), ans.end() );
    64     printf( "%d
    ", ans.size() );
    65     for( int t=0; t<ans.size(); t++ )
    66         printf( "%d ", ans[t] );
    67     printf( "
    " );
    68 }
    View Code
  • 相关阅读:
    高可用的MongoDB集群-实战篇
    【转载】特征选择常用算法综述
    【转载】Pytorch tutorial 之Datar Loading and Processing
    论文笔记系列-Well Begun Is Half Done:Generating High-Quality Seeds for Automatic Image Dataset Construction from Web
    重新定义Pytorch中的TensorDataset,可实现transforms
    【转载】机器学习之特征工程
    Pytorch里的CrossEntropyLoss详解
    Python日志模块logging用法
    【转载】如何进行数据变换
    【转载】使用sklearn优雅地进行数据挖掘
  • 原文地址:https://www.cnblogs.com/idy002/p/4344166.html
Copyright © 2011-2022 走看看