bzoj 1098: [POI2007]办公楼biu (补图+链表优化bfs)
来源:互联网 发布:linux 时间戳 编辑:程序博客网 时间:2024/05/16 16:23
1098: [POI2007]办公楼biu
Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 1204 Solved: 558
[Submit][Status][Discuss]
Description
FGD开办了一家电话公司。他雇用了N个职员,给了每个职员一部手机。每个职员的手机里都存储有一些同事的
电话号码。由于FGD的公司规模不断扩大,旧的办公楼已经显得十分狭窄,FGD决定将公司迁至一些新的办公楼。FG
D希望职员被安置在尽量多的办公楼当中,这样对于每个职员来说都会有一个相对更好的工作环境。但是,为了联
系方便起见,如果两个职员被安置在两个不同的办公楼之内,他们必须拥有彼此的电话号码。
Input
第一行包含两个整数N(2<=N<=100000)和M(1<=M<=2000000)。职员被依次编号为1,2,……,N.以下M行,每
行包含两个正数A和B(1<=A
Output
包含两行。第一行包含一个数S,表示FGD最多可以将职员安置进的办公楼数。第二行包含S个从小到大排列的
数,每个数后面接一个空格,表示每个办公楼里安排的职员数。
Sample Input
1 3
1 4
1 5
2 3
3 4
4 5
4 7
4 6
5 6
6 7
2 4
2 7
2 5
3 5
3 7
1 7
Sample Output
1 2 4
HINT
FGD可以将职员4安排进一号办公楼,职员5和职员7安排进2号办公楼,其他人进3号办公楼。
Source
题解:补图+链表优化bfs.
昨天查了一些关于补图的东西,再看这道题发现其实就是求补图的连通分量的个数。
所谓补图,就是将已有的边删去,没有的边加上。这样补图中有连边的两个点就是不彼此拥有电话号码的人,那么他们一定要在一栋办公楼里。
但是这个题的点数很多,而原图的边却很少。所以我们无法建立补图,需要在原图的基础上求补图的连通分量的大小及个数。
我们考虑一个点,有哪些点需要和他在一个连通分量中,与他有边相连的点必然不用,那么我们可以把与他相连的点标记,每次找出未标记且未分配的点加入队列,更新答案并进行扩展。注意每次做完之后要清相连点的标记,因为当前点的关系可以使两个人不在同一个楼办公,但是新加入队列中的点有可能需要这些点在同楼办公。
这样还是不能在科学的时间内出解。于是就出现了链表优化bfs。因为每次点都只能属于一个楼,那么我们用链表维护剩余的未分配的点,如果我们为一个点分配了办公楼,就将其从链表中删去,有效的减少了每个点被枚举的次数。
时间复杂度O(n+m)
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#define N 4000003using namespace std;int vis[N],n,m,num[N],ans;int point[N],next[N],v[N],tot,l[N],r[N],mark[N];void add(int x,int y){tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y;tot++; next[tot]=point[y]; point[y]=tot; v[tot]=x;//cout<<x<<" "<<y<<endl;}void del(int x){vis[x]=1;r[l[x]]=r[x];l[r[x]]=l[x];}void bfs(int x){queue<int> p; p.push(x);while(!p.empty()) { int now=p.front(); p.pop(); num[ans]++; for (int i=point[now];i;i=next[i]) mark[v[i]]=1; for (int i=r[0];i;i=r[i]) if (!vis[i]&&!mark[i]) del(i),p.push(i); for (int i=point[now];i;i=next[i]) mark[v[i]]=0;}}int main(){freopen("a.in","r",stdin);scanf("%d%d",&n,&m);for (int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); add(x,y); }for (int i=0;i<=n;i++) l[i]=i-1,r[i]=i+1;r[n]=0;for (int i=1;i<=n;i++) if(!vis[i]) { ans++; del(i); bfs(i); }sort(num+1,num+ans+1);printf("%d\n",ans);for (int i=1;i<=ans;i++) printf("%d ",num[i]);printf("\n");}
- bzoj 1098: [POI2007]办公楼biu (补图+链表优化bfs)
- BZOJ 1098: [POI2007]办公楼biu 补图联通块个数,链表优化
- 【BZOJ1098】[POI2007]办公楼biu【BFS/DFS】【链表优化】【补图】
- BZOJ 1098([POI2007]办公楼biu-链表优化Dfs)
- 【BZOJ】1098 [POI2007]办公楼biu 链表+BFS
- BZOJ 1098: [POI2007]办公楼biu 链表bfs
- BZOJ 1098: [POI2007]办公楼biu
- BZOJ 1098: [POI2007]办公楼biu
- bzoj 1098: [POI2007]办公楼biu
- bzoj-1098: [POI2007]办公楼biu
- [BZOJ]1098: [POI2007]办公楼biu
- BZOJ 1098: [POI2007]办公楼biu
- BZOJ 1098: [POI2007]办公楼biu 并查集优化bfs找反图联通块
- 1098: [POI2007]办公楼biu 链表+BFS
- BZOJ 1098 [POI2007]办公楼biu 链表
- 1098: [POI2007]办公楼biu
- 【BZOJ】【P1098】【POI2007】【办公楼biu】【题解】【链表+BFS】
- 【BFS+链表】BZOJ1098 [POI2007]办公楼biu
- makefile中变量定义的空格
- Android中Scroller实现弹性滑动的原理和实例应用
- Git 获取远程分支
- TCP/IP协议簇简介
- 一起学Netty(四)之 ChannelHandler,ChannelHandlerContext,ChannelPipeline
- bzoj 1098: [POI2007]办公楼biu (补图+链表优化bfs)
- POJ 2111 DP+记录路径
- 《大型网站技术架构》读书笔记之五:万无一失之网站的高可用架构
- C#中文件及文件夾的遍历
- 打印阵列
- swift_015(Swift 的函数)
- DateConverter does not support default String to ‘Date’ conversion.
- 使用Android API最佳实践
- 高性能服务器架构思路(一)——缓冲策略