# 解题思路

画画图可以发现,只要是两个点之间没有相互连边,那么就必须将这两个人安排到同一个办公楼内,如图所示:

那,我们可以建立补图,就是先建一张完全图,然后把题目中给出的边都删掉,这就是一张补图,显然补图中相互连边的点就放在同一栋办公楼内。

我们可以用并查集来完成,但是数据范围显然不允许用这样的方法,建图的复杂度是 $N^2$ 的。所以考虑另一种方法:

将原图建立好,在原图中,从一个点开始,把这个点所能够直接到达的点标记出来,这些点是不可以放在一起的。然后将这些点删除。

之后对每一个点都进行这样的操作,那么之后要删除的点都要满足既没有被删除也没有被标记。这样做下来的复杂度还是 $N^2$ 的。再来想想如何优化,我们如果在删点的时候,不去枚举那些已经被删除的点。那所有的删点的操作总时间复杂度是 $M$ 的,因为每个边都要只遍历一次。如何优化?链表啊。。。

# 附上代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
x = ; T f = ; char c = getchar();
while (c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while (c <= '' && c >= '') {x = x* + c-''; c = getchar();}
x *= f;
}
const int maxn = 4e6+;
int n, m, head[maxn], cnt, ans, pre[maxn], sur[maxn], num[maxn];
bool vis[maxn], del[maxn];
struct edge {int nxt, to;}ed[maxn];
inline void addedge(int x, int y) {
ed[++cnt].nxt = head[x], head[x] = cnt, ed[cnt].to = y;
}
inline void DEL(int x) {
sur[pre[x]] = sur[x];
pre[sur[x]] = pre[x];
del[x] = ;
}
inline void BFS(int u) {
queue<int> Q;
Q.push(u), vis[u] = ;
while (!Q.empty()) {
int now = Q.front();
Q.pop();
num[ans] ++;
for(int i=head[now]; i; i=ed[i].nxt)
vis[ed[i].to] = ;
for(int i=sur[]; i<=n; i=sur[i])
if(!vis[i] && !del[i]) Q.push(i), DEL(i);
for(int i=head[now]; i; i=ed[i].nxt)
vis[ed[i].to] = ;
}
}
int main() {
read(n), read(m);
int u, v;
for(int i=; i<=m; i++) {
read(u), read(v);
addedge(u, v), addedge(v, u);
}
for(int i=; i<=n; i++)
pre[i] = i-, sur[i] = i+;
for(int i=; i<=n; i++)
if(!del[i]) del[i] = , ans ++, BFS(i), DEL(i);
sort(num+, num++ans);
printf("%d\n", ans);
for(int i=; i<=ans; i++) printf("%d ", num[i]);
return ;
}

bzoj 1098 [POI2007] 办公楼 biu的更多相关文章

  1. bzoj 1098 [POI2007]办公楼biu bfs+补图+双向链表

    [POI2007]办公楼biu Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1543  Solved: 743[Submit][Status][Di ...

  2. [BZOJ 1098] [POI2007] 办公楼biu 【链表优化BFS】

    题目链接:BZOJ - 1098 题目分析 只有两个点之间有边的时候它们才能在不同的楼内,那么就是说如果两个点之间没有边它们就一定在同一座楼内. 那么要求的就是求原图的补图的连通块. 然而原图的补图的 ...

  3. 【刷题】BZOJ 1098 [POI2007]办公楼biu

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

  4. BZOJ 1098 [POI2007]办公楼biu(反向图bfs+并查集优化)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1098 [题目大意] 现在有一张图,要求将这张图的点划分为尽量多的分组,对于不同分组的两 ...

  5. bzoj 1098 [POI2007]办公楼biu——链表

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1098 求补图的连通块大小.与自己没有边的和自己在一个连通块里. 用链表把所有点串起来.先给自 ...

  6. BZOJ 1098: [POI2007]办公楼biu 链表

    求补图连通块,用链表优化,势能O(n+m) #include<cstdio> #include<cstring> #include<iostream> #inclu ...

  7. 【BZOJ】1098: [POI2007]办公楼biu(补图+bfs+链表)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1098 显然答案是补图连通块..... 想到用并查集...可是连补图的边都已经...n^2了...怎么 ...

  8. bzoj 1098 poi2007 办公楼 bfs+链表

    题意很好理解,求给出图反图的联通块个数. 考虑这样一个事情:一个联通块里的点,最多只会被遍历一次,再遍历时没有任何意义 所以用链表来存,每遍历到一个点就将该点删掉 #include<cstdio ...

  9. BZOJ1098: [POI2007]办公楼biu

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

随机推荐

  1. .net 下webservice 的WebMethod的属性

    WebMethod有6个属性: .Description .EnableSession .MessageName .TransactionOption .CacheDuration .BufferRe ...

  2. bzoj 2780: [Spoj]8093 Sevenk Love Oimaster【广义SAM】

    AC自动机比较简单,把询问串做成AC自动机然后模板串边跑变更新即可 SAM是把模板串做成广义SAM,然后每个节点存有几个模板串经过,具体方法是每次更新暴力向上跳直到有时间戳我不会证为什么时间复杂度是对 ...

  3. 第十六篇 .NET高级技术之序列化

    .net framework的类库中提供了三个可以用于序列化和反序列化的类,分别为BinaryFormatter.SoapFormatter和XmlSerializer. BinaryFormatte ...

  4. 查看软件安装的位置 Ubuntu

    Ubuntu和windows不一样,不是所有的软件都在一个文件夹,而是不同类型的分散在不同的文件夹下 所以查找起来也是不同的 如果知道是用 apt-get install 方法安装的,可以直接用 dp ...

  5. P2024 [NOI2001]食物链

    第一种说法是"1 X Y",表示 X 和 Y 是同类. 第二种说法是"2 X Y",表示 X 吃 Y . 根据这句话 可以看出来这是一个种类并查集 种类并查集 ...

  6. 使用Git分布式版本控制系统

    GIT(分布式版本控制系统) Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目.   Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本 ...

  7. [洛谷4329/COCI2006-2007#1] Bond

    Description Everyone knows of the secret agent double-oh-seven, the popular Bond (James Bond). A les ...

  8. Android课程设计第六天欢迎界面(跳转)

    注意:课程设计只为完成任务,不做细节描述~ package com.example.myapplication; import android.app.Activity; import android ...

  9. 从一个n位数中选出m位按顺序组成新数并使其最大 || Erasing and Winning UVA - 11491

    就是从n位数中取出n-d个数字按顺序排成一排组成一个新数使得其最大 算法: 从前往后确定每一位.找第i位时,要求后面留下d-i位的空间, 因此第i位应该从第i-1位原来位置+1到第d+i位寻找 用线段 ...

  10. 477 Total Hamming Distance 汉明距离总和

    两个整数的 汉明距离 指的是这两个数字的二进制数对应位不同的数量.计算一个数组中,任意两个数之间汉明距离的总和.示例:输入: 4, 14, 2输出: 6解释: 在二进制表示中,4表示为0100,14表 ...