并查集+dfs

先开始想和不相连的点用并查集连起来,最后看每个连通块有多少个点就行了,但是这样是O(n*n)的,然而我并没有想到补图

其实就是求补图有多少连通块,因为补图中两个点有边,那么这两个点必须在一栋大楼里,因为他们之间没有联系,然后这样就有了许多连通块,不同的连通块可以不相连,因为不同的连通块之间没有边,也就是不同的连通块的点之间都有联系,然后我们只要求出这样的连通块的数量和大小。

但是补图太稠密,不能直接求,然后我们就要用奇技淫巧来优化,我们用并查集维护每个点,用并查集维护下一个没有用过的点是哪个,然后我们dfs,用并查集查询下一个没有访问过的点,然后判断当前的点和那个点在原图中是否相连,相连的话说明这两个点在补图中没有边,没有必要访问,因为两个点或许不在一个连通块内,而且两个点在补图中不相连,自然不会访问。如果一个点已经被访问,那么自然不会再次访问,于是,每个点访问一次,边访问一次,复杂度O(n+m)

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N = ;
  4. int n, m, cnt;
  5. int fa[N], ans[N];
  6. vector<int> G[N];
  7. inline int read()
  8. {
  9. int x = , f = ; char c = getchar();
  10. while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
  11. while(c >= '' && c <= '') { x = x * + c - ''; c = getchar(); }
  12. return x * f;
  13. }
  14. int find(int x)
  15. {
  16. return x == fa[x] ? x : fa[x] = find(fa[x]);
  17. }
  18. void dfs(int u)
  19. {
  20. ++ans[cnt];
  21. fa[u] = find(u + );
  22. for(int i = find(); i <= n; i = find(i + ))
  23. {
  24. bool flag = true;
  25. for(int j = ; j < G[u].size(); ++j)
  26. {
  27. int v = G[u][j];
  28. if(v == i)
  29. {
  30. flag = false;
  31. break;
  32. }
  33. }
  34. if(flag) dfs(i);
  35. }
  36. }
  37. int main()
  38. {
  39. n = read();
  40. m = read();
  41. for(int i = ; i <= m; ++i)
  42. {
  43. int u = read(), v = read();
  44. G[u].push_back(v);
  45. G[v].push_back(u);
  46. }
  47. for(int i = ; i <= n + ; ++i) fa[i] = i;
  48. for(int i = ; i <= n; ++i) if(fa[i] == i)
  49. {
  50. ++cnt;
  51. dfs(i);
  52. }
  53. printf("%d\n", cnt);
  54. sort(ans + , ans + cnt + );
  55. for(int i = ; i <= cnt; ++i) printf("%d ", ans[i]);
  56. return ;
  57. }

bzoj1098的更多相关文章

  1. 【bzoj1098】办公楼

    [bzoj1098]办公楼 题意 FGD开办了一家电话公司.他雇用了N个职员,给了每个职员一部手机.每个职员的手机里都存储有一些同事的电话号码.由于FGD的公司规模不断扩大,旧的办公楼已经显得十分狭窄 ...

  2. 5098: [BZOJ1098][POI2007]办公楼biu

    5098: [BZOJ1098][POI2007]办公楼biu 没有数据结构就很棒 一个看上去非常玄学的代码 const int N=1e5+10,M=2e6+10; int n,m; int fa[ ...

  3. BZOJ1098: [POI2007]办公楼biu

    从问题可以看出是求补图的连通块及点数 但补图太大.所以考虑缩小规模. 当一个点归属于一个连通块后,它以后就不需要了.所以可以用链表,删去这个点,也就减小了规模. 一个点开始bfs,每个点只会进队一次, ...

  4. bzoj1098 1301

    这两题很类似,都是在补图上搜索 但是由于补图太大我们不能建出来 考虑先从一个点搜,每次搜可以搜的点, 然后维护一个链表,记录当前还没有搜过的点,搜过之后从链表中删除即可 type node=recor ...

  5. 【链表】Bzoj1098[POI2007]办公楼biu

    Description FGD开办了一家电话公司.他雇用了N个职员,给了每个职员一部手机.每个职员的手机里都存储有一些同事的电话号码.由于FGD的公司规模不断扩大,旧的办公楼已经显得十分狭窄,FGD决 ...

  6. bzoj1098 办公楼

    Description FGD开办了一家电话公司.他雇用了N个职员,给了每个职员一部手机.每个职员的手机里都存储有一些同事的电话号码.由于FGD的公司规模不断扩大,旧的办公楼已经显得十分狭窄,FGD决 ...

  7. 【BZOJ1098】[POI2007]办公楼biu

    题目一开始看以为和强联通分量有关,后来发现是无向边,其实就是求原图的补图的联通块个数和大小.学习了黄学长的代码,利用链表来优化,其实就是枚举每一个人,然后把和他不相连的人都删去放进同一个联通块里,利用 ...

  8. BZOJ1098 POI2007 办公楼biu 【链表+bfs】

    Description FGD开办了一家电话公司.他雇用了N个职员,给了每个职员一部手机.每个职员的手机里都存储有一些同事的电话号码.由于FGD的公司规模不断扩大,旧的办公楼已经显得十分狭窄,FGD决 ...

  9. Connected Components? Codeforces - 920E || 洛谷 P3452 &&bzoj1098 [POI2007]BIU-Offices

    https://codeforces.com/contest/920/problem/E https://www.luogu.org/problemnew/show/P3452 https://www ...

随机推荐

  1. datetimebox赋值或取值

    datetimebox赋值或取值 $('#j_dateStart').datebox('setValue', ""); //赋予空值 $("#j_dateStart&qu ...

  2. Gym - 101670B Pond Cascade(CTU Open Contest 2017 贪心,二分)

    题目: The cascade of water slides has been installed in the park recently and it has to be tested. The ...

  3. Flask保存或解压上传的文件

    import os import uuid import shutil import zipfile from flask import Flask, render_template, request ...

  4. Tree(树的还原以及树的dfs遍历)

    紫书:P155 uva  548   You are to determine the value of the leaf node in a given binary tree that is th ...

  5. 【Codeforces 682C】Alyona and the Tree

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 设dis[v]表示v以上的点到达这个点的最大权值(肯定是它的祖先中的某个点到这个点) 类似于最大连续累加和 当往下走(x,y)这条边的时候,设 ...

  6. [luoguP2285] [HNOI2004]打鼹鼠(DP)

    传送门 设f[i]表示i个鼹鼠出现后,打死鼹鼠的最大值 动态转移方程:f[i]=max{f[j]+1}, 条件:abs(x[i]-x[j])+abs(y[i]-y[j])<=time[i]-ti ...

  7. Codeforces Round #232 (Div. 2) C

    C. On Number of Decompositions into Multipliers time limit per test 1 second memory limit per test 2 ...

  8. mybatis表关联彻底理解

    1.多张表关联 三张表,用户表,主播表,关注表. 查询用户已经关注的主播的信息,那就要三张表关联起来啊.分别left join联在一起,通过id相同的连接在一起.最后where查找出最终条件. < ...

  9. MVC中从控制器到视图的数据传递方法汇总

    1.ViewData对象概述ViewData是一种字典集合数据,是"视图基类"和"控制器基类"的属性常见用法是在控制器中写入数据,在视图中读取数据ViewDat ...

  10. [Algorithm] Determine if two strings are an anagram

    The anagram test is commonly used to demonstrate how an naive implementation can perform significant ...