# 解题思路

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

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

我们可以用并查集来完成,但是数据范围显然不允许用这样的方法,建图的复杂度是 $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. SCUT - 254 - 欧洲爆破 - 概率dp - 状压dp

    https://scut.online/p/254 思路很清晰,写起来很恶心. #include<bits/stdc++.h> using namespace std; #define l ...

  2. Codeforces Round #436 (Div. 2) E. Fire(背包+记录路径)

    传送门 题意 给出n种物品,抢救第\(i\)种物品花费时间\(t_i\),价值\(p_i\),截止时间\(d_i\) 询问抢救的顺序及物品价值和最大值 分析 按\(d_i\)排序的目的是防止以下情况 ...

  3. python 基本类型的创建方法

    1.int class int(object) | int(x=0) -> integer | int(x, base=10) -> integer | | Convert a numbe ...

  4. vue父组件调用子组件方法

    父组件: 代码 <sampleapplylinemodel ref="sampleapplylinemodel" @reLoad="_fetchRecords&qu ...

  5. 【POJ - 3190 】Stall Reservations(贪心+优先队列)

    Stall Reservations 原文是English,这里直接上中文吧 Descriptions: 这里有N只 (1 <= N <= 50,000) 挑剔的奶牛! 他们如此挑剔以致于 ...

  6. noi.ac 邀请赛1 By cellur925

    A. array 考场:上来就想暴力,首先第一个子任务肯定没问题,怎么搞都行.然后第二个子任务用个数组记下新修的值就行了.第三个子任务用一下等差数列求和公式帮助求解,每次都重新算(因为每次改变全部元素 ...

  7. dos 下 批量替换 只支持txt

    首先必须存成 bat 格式,其次识别不了word 1.bat ##替换12 成12*3 @echo offsetlocal enabledelayedexpansionfor /F "tok ...

  8. 122 Best Time to Buy and Sell Stock II 买卖股票的最佳时机 II

    假设有一个数组,它的第 i 个元素是一个给定的股票在第 i 天的价格.设计一个算法来找到最大的利润.你可以完成尽可能多的交易(多次买卖股票).然而,你不能同时参与多个交易(你必须在再次购买前出售股票) ...

  9. scau 17967 大师姐唱K的固有结界 分类暴力 + RMQ

    由于能放两次,那么分类, 1.连续使用,(这个直接O(n^2)暴力) 2.分开使用. 分开使用的话,首先暴力枚举,用T时间,能从第1个位置,唱到第几首歌,然后剩下的就是从pos + 1, n这个位置, ...

  10. Keepalived+Nginx实现Nginx的高可用

    集群规划 主机名 IP VIP Nginx:port KeepAlived主备 KA_NG_01 192.168.30.130 192.168.30.120 8088 MASTER KA_NG_02 ...