Educational Codeforces Round 37 E. Connected Components? 链表+bfs
2018-02-04 23:52
393 查看
首先感谢qls群里 提思路,佩服
题意:
给定n个点;m条说明:那两个点之间没边;
问 有多少个连通块,每个的大小按非递减顺序输出;
思路:
很容易想到根据没连边,找到边,然后对点进行dfs,找到连通块标记出来就是了,但是复杂度行不通;
这个过程中,复杂度高的地方是每次要便利所有的数看是否有边;
后来借鉴qls想法,先对所有的点建立链表,然后每次bfs把某个连通块的点拿出来,
因为没连的边的最多有2e5条,所以链表的大小会减少的很快,复杂度也就降了下来;
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<queue>
#include<list>
#include<stack>
#include<map>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI acos(-1.0)
#define in freopen("in.txt", "r", stdin)
#define out freopen("out.txt", "w", stdout)
#define kuaidian ios::sync_with_stdio(0);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 2e5 + 7, maxd = 1e5 + 7;
const int mod = 1e9 + 7;
const int INF = 0x7f7f7f7f;
int n, m;
list<int> lis;
vector<int> vec[maxn], ans;
bool vis1[maxn], vis2[maxn];
void init() {
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; ++i)
lis.push_back(i);
for(int i = 0; i < m; ++i) {
int u, v;
scanf("%d %d", &u, &v);
vec[u].push_back(v);
vec[v].push_back(u);
}
}
int bfs(int id) {
int res = 0;
queue<int> qu;
qu.push(id);
while(!qu.empty()) {
int u = qu.front(); qu.pop();
if(vis1[u]) continue;
vis1[u] = 1; res++;
for(auto &v : vec[u]) vis2[v] = 1;
for(auto i = lis.begin(); i != lis.end(); ) {
int v = *i;
if(vis2[v]) {
i++;
continue;
}
qu.push(v);
lis.erase(i++);
}
for(auto &v : vec[u]) vis2[v] = 0;
}
return res;
}
void solve() {
for(int i = 1; i <= n; ++i) {
if(vis1[i]) continue;
ans.push_back(bfs(i));
}
sort(ans.begin(), ans.end());
printf("%d\n", ans.size());
for(int i = 0; i < ans.size(); ++i) {
printf("%d ", ans[i]);
}
}
int main() {
init();
solve();
return 0;
}
/*
5 5
1 2
3 4
3 2
4 2
2 5
*/
题意:
给定n个点;m条说明:那两个点之间没边;
问 有多少个连通块,每个的大小按非递减顺序输出;
思路:
很容易想到根据没连边,找到边,然后对点进行dfs,找到连通块标记出来就是了,但是复杂度行不通;
这个过程中,复杂度高的地方是每次要便利所有的数看是否有边;
后来借鉴qls想法,先对所有的点建立链表,然后每次bfs把某个连通块的点拿出来,
因为没连的边的最多有2e5条,所以链表的大小会减少的很快,复杂度也就降了下来;
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<queue>
#include<list>
#include<stack>
#include<map>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI acos(-1.0)
#define in freopen("in.txt", "r", stdin)
#define out freopen("out.txt", "w", stdout)
#define kuaidian ios::sync_with_stdio(0);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 2e5 + 7, maxd = 1e5 + 7;
const int mod = 1e9 + 7;
const int INF = 0x7f7f7f7f;
int n, m;
list<int> lis;
vector<int> vec[maxn], ans;
bool vis1[maxn], vis2[maxn];
void init() {
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; ++i)
lis.push_back(i);
for(int i = 0; i < m; ++i) {
int u, v;
scanf("%d %d", &u, &v);
vec[u].push_back(v);
vec[v].push_back(u);
}
}
int bfs(int id) {
int res = 0;
queue<int> qu;
qu.push(id);
while(!qu.empty()) {
int u = qu.front(); qu.pop();
if(vis1[u]) continue;
vis1[u] = 1; res++;
for(auto &v : vec[u]) vis2[v] = 1;
for(auto i = lis.begin(); i != lis.end(); ) {
int v = *i;
if(vis2[v]) {
i++;
continue;
}
qu.push(v);
lis.erase(i++);
}
for(auto &v : vec[u]) vis2[v] = 0;
}
return res;
}
void solve() {
for(int i = 1; i <= n; ++i) {
if(vis1[i]) continue;
ans.push_back(bfs(i));
}
sort(ans.begin(), ans.end());
printf("%d\n", ans.size());
for(int i = 0; i < ans.size(); ++i) {
printf("%d ", ans[i]);
}
}
int main() {
init();
solve();
return 0;
}
/*
5 5
1 2
3 4
3 2
4 2
2 5
*/
相关文章推荐
- Educational Codeforces Round 37 E. Connected Components?(bfs)
- Educational Codeforces Round 37 E. Connected Components?(bfs)
- Educational Codeforces Round 37 (Rated for Div. 2) E. Connected Components?(连通分量的个数,STL)
- Educational Codeforces Round 37-E.Connected Components?题解
- Educational Codeforces Round 37 E. Connected Components?(bfs+思路)
- Educational Codeforces Round 37 E. Connected Components?(920E)
- Wannafly挑战赛9+Educational Codeforces Round 37 (Rated for Div. 2)
- 【Educational Codeforces Round 10E】【双连通分量缩环 BFS】Pursuit For Artifacts 从ST到ED每条边最多经过一次能否经过任一特殊边
- Educational Codeforces Round 37 (Rated for Div. 2)
- Educational Codeforces Round 37 F - SUM and REPLACE (线段树)
- Educational Codeforces Round 37 (Rated for Div. 2)(A、B、C)
- Educational Codeforces Round 37-F.SUM and REPLACE题解
- Educational Codeforces Round 37 (Rated for Div. 2) 920E E. Connected Components?
- codeforces 920 EFG 题解合集 ( Educational Codeforces Round 37 )
- Educational Codeforces Round 37
- Educational Codeforces Round 37
- Educational Codeforces Round 37-G.List Of Integers题解
- Educational Codeforces Round 37 [Codeforces920]
- [Codeforces]Educational Codeforces Round 37 (Rated for Div. 2)
- Educational Codeforces Round 37 (Rated for Div. 2)-F-SUM and REPLACE(线段树)