CodeForces-920E Connected Components? 广度搜索 双向链表 判断联通 大量重复节点的删除
2018-07-29 17:06
519 查看
题目链接:https://cn.vjudge.net/problem/CodeForces-920E
题意
给一个补图,问各个联通块有几个元素,升序排列
注意maxn=2e5, maxm=2e10
思路
数据量超大,这本来是并查集专题的一道题
如果用并查集的话,向上维护一个元素个数,但首先离线建图是个问题O(n^2)
这样考虑的话,bfs O(n)就是更好的选择
提交上去TLE,当时写题没仔细算复杂度,set查边+数组判重,加起来貌似O(nlogn+n),至于为什么用set查边,因为数组查边肯定空间太大
最后查了查题解,判重是链表删除元素,相当于真正的删除了,循环次数大大降低了
好么,厉害
提交过程
CE | 头文件 |
TLE1 | set<pair<int, int>>存边 |
TLE2 | 改成set |
WA1-3 | 忘了为啥WA了... |
AC |
代码
#include <set> #include <queue> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=2e5+20; int n, m, cnt, size[maxn], next[maxn], prev[maxn]; bool check[maxn]; set<long long> vis; void del(int x){ next[prev[x]]=next[x]; prev[next[x]]=prev[x]; } int bfs(int x){ int ans=1; queue<int> que; que.push(x); check[x]=true; del(x); while (que.size()){ int node=que.front(); que.pop(); for (int i=next[0]; i<=n; i=next[i]) if (!check[i] && !vis.count((long long)i*maxn+node)){ que.push(i); check[i]=true; del(i); ans++; } }return ans; } int main(void){ int to, from; scanf("%d%d", &n, &m); for (int i=0; i<m; i++){ scanf("%d%d", &to, &from); vis.insert((long long)to*maxn+from); vis.insert((long long)from*maxn+to); } for (int i=1; i<=n; i++) next[i]=i+1, prev[i]=i-1; next[0]=1; prev[n+1]=n; int cnt=0; for (int i=1; i<=n; i++) if (!check[i]) size[cnt++]=bfs(i); sort(size, size+cnt); printf("%d\n", cnt); for (int i=0; i<cnt; i++) printf("%d%c", size[i], " \n"[i==cnt-1]); return 0; }
Time | Memory | Length | Lang | Submitted |
---|---|---|---|---|
343ms | 16012kB | 1067 | GNU G++ 5.1.0 | 2018-07-23 17:51:00 |
相关文章推荐
- 单链表的创建和遍历、求单链表中节点的个数、查找单链表中的中间结点、判断单链表是否有环、取出有环链表中环的长度,删除有序链表中的重复结点
- 删除链表的重复节点
- 删除链表中重复的节点
- STL双向链表之删除重复元素(list)
- 《剑指offer》删除链表中重复的节点
- [原]C语言实现双向链表删除节点、插入节点、双向输出等操作
- 删除链表中的元素//p=pre;//重复的1-1,要判断重复判读。hh->next=head;//头上加头,不用考虑链表换头
- 删除链表中重复的节点
- 【IT笔试面试题整理】删除无序链表中重复的节点
- 删除链表中的重复节点
- 双向链表的节点删除
- 将链表中数据域为key 的节点删除(链表有重复值)
- 数据结构——12 删除两个双向链表中相同的节点
- 判断链表是否为空、求链表长度、插入新节点、删除节点、链表排序
- 删除链表中重复的节点
- LeetCode 刷题: 删除已排序链表中的重复节点
- 删除排序链表中重复的节点 递归方式
- 判断链表相交,删除无头单链表的非尾节点及倒序打印单链表——题集(四)
- 删除链表中的重复节点、剩余节点逆序输出
- Leetcode:Remove Duplicates from Sorted List 删除单链表中重复的节点