5098: [BZOJ1098][POI2007]办公楼biu
[BZOJ1098][POI2007]办公楼biu
一个看上去非常玄学的代码
const int N=1e5+10,M=2e6+10;
int n,m;
int fa[N];
int Find(int x){ return fa[x]==x?x:fa[x]=Find(fa[x]); }
vector <int> G[N];
typedef vector <int> ::iterator iter;
void merge(int x,int y){
x=Find(x),y=Find(y);
if(x==y) return;
vector <int> tmp;tmp.clear();
if(G[x].size()>G[y].size()) swap(x,y);
int p=0;
for(reg int i=0;i<(int)G[x].size();i++){
while(p<(int)G[y].size()&&G[y][p]<G[x][i]) p++;
if(p>=(int)G[y].size()||G[y][p]!=G[x][i]) {
tmp.push_back(G[x][i]);
G[x].erase(G[x].begin()+i);
i--;
}
}
fa[y]=x;
rep(i,0,tmp.size()-1) merge(x,tmp[i]);
}
int cnt[N];
int ans[N],ac;
bool go[N];
void Sort(vector <int> &V){
if(V.size()<20000) return sort(V.begin(),V.end());
memset(go,0,sizeof go);
rep(i,0,V.size()) go[V[i]]=true;
V.clear();
rep(i,1,n) if(go[i]) V.push_back(i);
}
int num[N];
bool cmp(int x,int y){
return G[x].size()<G[y].size();
}
int main(){
n=rd(),m=rd();
rep(i,1,n) fa[i]=num[i]=i;
rep(i,1,m) {
int u=rd(),v=rd();
G[u].push_back(v);
G[v].push_back(u);
}
rep(i,1,n) Sort(G[i]);
sort(num+1,num+n+1,cmp);
rep(i,1,n) if(Find(num[i])==num[i]) {
memset(go,0,sizeof go);
rep(j,0,G[num[i]].size()-1) go[G[num[i]][j]]=1;
rep(j,1,n) if(num[i]!=j&&!go[j]) merge(num[i],j);
}
rep(i,1,n) cnt[Find(i)]++;
rep(i,1,n) if(cnt[i]) ans[++ac]=cnt[i];
sort(ans+1,ans+ac+1);
printf("%d\n",ac);
rep(i,1,ac) printf("%d",ans[i]),putchar(i==ac?'\n':' ');
}
我这个代码大概是在讲这样的:
按照出度排序,没有连边的点必须合并,最后找集合个数
但是合并的时候要注意用y的答案更新x,这样y就不用再跑一次了(这里的总复杂度较为诡异)
更新过程:遍历x的边,如果y的边中没有x的这条边,那么就将其删去,并且将这个点合并
首先根据鸽巢原理,出度最小的点最大出度必然是\(\frac{m}{n}\)
它的边数也是\(\frac{m}{n}\)
每次和其他的点合并,这个复杂度是 \(\frac{m}{n} \cdot m\) (事实上是远远跑不到的!因为每次都会删去大量的边!)
复杂度似乎是有保证的
然后由于合并完之后也就剩下不到\(\frac{m}{n}\)个点了,所以这里就算你暴力\(O(n)\)合并也没关系
最后是你们担心的\(\frac{m}{n} \cdot m\)会TLE
瞪眼一看当\(m=2e6,n\)较小时就T了
哪你n较小时直接跑\(O(n^2)\)不就是了 吐舌头
注意时限是20s的这个代码还根本跑不满,所以自然不用担心!
tips: vector可以用链表优化更棒
5098: [BZOJ1098][POI2007]办公楼biu的更多相关文章
- BZOJ1098: [POI2007]办公楼biu
从问题可以看出是求补图的连通块及点数 但补图太大.所以考虑缩小规模. 当一个点归属于一个连通块后,它以后就不需要了.所以可以用链表,删去这个点,也就减小了规模. 一个点开始bfs,每个点只会进队一次, ...
- 【链表】Bzoj1098[POI2007]办公楼biu
Description FGD开办了一家电话公司.他雇用了N个职员,给了每个职员一部手机.每个职员的手机里都存储有一些同事的电话号码.由于FGD的公司规模不断扩大,旧的办公楼已经显得十分狭窄,FGD决 ...
- BZOJ1098 POI2007 办公楼biu 【链表+bfs】
Description FGD开办了一家电话公司.他雇用了N个职员,给了每个职员一部手机.每个职员的手机里都存储有一些同事的电话号码.由于FGD的公司规模不断扩大,旧的办公楼已经显得十分狭窄,FGD决 ...
- bzoj 1098 [POI2007]办公楼biu bfs+补图+双向链表
[POI2007]办公楼biu Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 1543 Solved: 743[Submit][Status][Di ...
- 【BZOJ1098】[POI2007]办公楼biu
题目一开始看以为和强联通分量有关,后来发现是无向边,其实就是求原图的补图的联通块个数和大小.学习了黄学长的代码,利用链表来优化,其实就是枚举每一个人,然后把和他不相连的人都删去放进同一个联通块里,利用 ...
- 【BZOJ】1098: [POI2007]办公楼biu(补图+bfs+链表)
http://www.lydsy.com/JudgeOnline/problem.php?id=1098 显然答案是补图连通块..... 想到用并查集...可是连补图的边都已经...n^2了...怎么 ...
- 【刷题】BZOJ 1098 [POI2007]办公楼biu
Description FGD开办了一家电话公司.他雇用了N个职员,给了每个职员一部手机.每个职员的手机里都存储有一些同事的 电话号码.由于FGD的公司规模不断扩大,旧的办公楼已经显得十分狭窄,FGD ...
- bzoj 1098 [POI2007] 办公楼 biu
# 解题思路 画画图可以发现,只要是两个点之间没有相互连边,那么就必须将这两个人安排到同一个办公楼内,如图所示: 那,我们可以建立补图,就是先建一张完全图,然后把题目中给出的边都删掉,这就是一张补图, ...
- [POI2007]办公楼biu
Description FGD开办了一家电话公司.他雇用了N个职员,给了每个职员一部手机.每个职员的手机里都存储有一些同事的电话号码.由于FGD的公司规模不断扩大,旧的办公楼已经显得十分狭窄,FGD决 ...
随机推荐
- 2019 第一视频java面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.第一视频等公司offer,岗位是Java后端开发,因为发展原因最终选择去了第一视频,入职一年时间了,也成为了面 ...
- 全程实操cdh5.14.4中集成安装kylin2.4.1与使用测试
在cdh5.14.4安装完成并排错完成的情况下,进行如下kylin安装操作: 1.实验环境 三台CentOS 7主机,IP地址 192.168.43.129 cm1 192.168.43.130 cm ...
- Vue3.0报错error: Unexpected console statement (no-console) 解决办法
写项目过程中用ESLint遵守代码规范很有必要,但是对于一些规范也很是无语,比如:‘Unexpected console statement (no-console)’,连console都不能用,这就 ...
- 浅谈HTML5的新特性
2014年10月29日,W3C宣布,经过接近8年的艰苦努力,HTML5标准规范终于制定完成. HTML5将会取代1999年制定的HTML 4.01.XHTML 1.0标准,使网络标准达到符合当代的网络 ...
- Java集合学习(6):LinkedHashSet
一.概述 首先我们需要知道的是它是一个Set的实现,所以它其中存的肯定不是键值对,而是值.此实现与HashSet的不同之处在于,LinkedHashSet维护着一个运行于所有条目的双重链接列表.此链接 ...
- 你与BAT只差这一套面试题
1.Linux如何挂载windows下的共享目录?mount.cifs //IP地址/server /mnt/server -o user=administrator,password=123456l ...
- Web架构之路:MongoDB集群及高可用实践
MongoDB集群有副本集及主从复制两种模式,不过主从模式在MongoDB 3.6已经彻底废弃,今天主要探讨副本集的搭建和使用,以及分片. 副本集介绍 副本集(Replica Set)即副本的集合,在 ...
- Nginx 反向代理与负载均衡的配置
已经很久没有写博了,因为最近学车加上各种问题一直没时间, 今天刚好想起有好多的东西还没来得及记录.回到正题: Nginx是一个非常强大的web轻量级服务器,许多大厂也用Nginx进行负载均衡和反向代理 ...
- SaltStack--快速入门
saltstack快速入门 saltstack介绍 Salt,一种全新的基础设施管理方式,部署轻松,在几分钟内可运行起来,扩展性好,很容易管理上万台服务器,速度够快,服务器之间秒级通讯 主要功能远程执 ...
- zabbix--图形字体乱码
解决 zabbix 图形字体乱码 如图:修改之前 具体步骤: 1)下载字体,例如:SIMKAI.ttf楷体(也可直接将Windows上的直接上传:Windows路径:C:\Windows\Fonts) ...