您的位置:首页 > 其它

Educational Codeforces Round 37 (Rated for Div. 2) E. Connected Components?(连通分量的个数,STL)

2018-02-03 11:14 555 查看

描述

You are given an undirected graph consisting of n vertices and edges.

Instead of giving you the edges that exist in the graph, we give you m

unordered pairs (x, y) such that there is no edge between x and y, and

if some pair of vertices is not listed in the input, then there is an

edge between these vertices.

You have to find the number of connected components in the graph and

the size of each component. A connected component is a set of vertices

X such that for every two vertices from this set there exists at least

one path in the graph connecting these vertices, but adding any other

vertex to X violates this rule.

Input

The first line contains two integers n and m (1 ≤ n ≤ 200000, ).

Then m lines follow, each containing a pair of integers x and y

(1 ≤ x, y ≤ n, x ≠ y) denoting that there is no edge between x and y.

Each pair is listed at most once; (x, y) and (y, x) are considered the

same (so they are never listed in the same test). If some pair of

vertices is not listed in the input, then there exists an edge between

those vertices.

Output

Firstly print k — the number of connected components in this graph.

Then print k integers — the sizes of components. You should output

these integers in non-descending order.

input

5 5
1 2
3 4
3 2
4 2
2 5


output

2
1 4


思路

给你了一个nn个点的无向图,然后有mm条边,然后题目会给出这mm条边的信息,代表这些边不存在。问这个图中有几个连通分量,输出连通分量的数目,然后按照递增顺序输出个数

思路就是,用
set
存储边的信息,然后遍历每一个点,建立一个队列,把当前点的以及所连的边删去,用一个
vector
来计数,最后输出答案。

思路很简单,主要在于实现。。

代码

#include <cstdio>
#include <cstring>
#include <cctype>
#include <stdlib.h>
#include <string>
#include <map>
#include <iostream>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
#define inf 1000000
#define mem(a,b) memset(a,b,sizeof(a))
const int N=200000+7;
set<int>s
,todo;
int main()
{
ios_base::sync_with_stdio(0);
int n,m,u,v;
cin>>n>>m;
for(int i=1; i<=m; i++)
{
cin>>u>>v;
s[u].insert(v);
s[v].insert(u);
}
vector<int>ans;
for(int i=1; i<=n; i++)
todo.insert(i);//当前要遍历的点的集合
while(!todo.empty())
{
queue<int>q;
ans.push_back(0);
q.push(*todo.begin());//把集合中的第一个点加入队列
todo.erase(q.front());//删除队首的点
while(!q.empty())
{
int u=q.front();
q.pop();
ans.back()++;
set<int>buf;
for(auto &i:todo)
if(s[u].find(i)==s[u].end())//如果存在边(u,i),就加入队列后删去
{
q.push(i);
buf.insert(i);
}
for(auto i:buf)
todo.erase(i);
}
}
sort(ans.begin(),ans.end());
cout<<ans.size()<<endl;
for(auto i:ans)
cout<<i<<" ";
cout<<endl;
return 0;
}


e794
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: