Educational Codeforces Round 37 E. Connected Components?(bfs+思路)

E. Connected Components?
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 ≤ nx ≠ 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.

Example
input
5 5
1 2
3 4
3 2
4 2
2 5
output
2
1 4 

題意:給出n個點,m條不存在的邊(除了不存在的邊其他邊都存在),輸出有多少個連通分量,以及每個連通分量裏點的個數(從小到大)

首先是存圖,2e5*2e5的圖,而且邊又經常用到,用鄰接表肯定是不行的,二維map可以解決這個問題

然後是優化,一個連通分量中的點都在同一個集合裏,由於是無向圖,對於一個連通分量中的點,他們之間可能會連很多條邊,但只需要一條邊就能確定他們之間的關係,所以其他那麼多條邊都可以優化掉,利用bfs,每次把v刪掉,然後看剩下所有沒加入集合中的點是否與v有關係,有關係則加入一個集合裏,再把這點刪了,重複這個過程即可

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int N=200005;
map<int,bool>e[N];
vector<int>mp,ans;
int bfs(int v)
{
    int cnt=0;
    queue<int>Q;
    Q.push(v);
    while(!Q.empty())
    {
        int u=Q.front();
        Q.pop();
        cnt++;
        for(int i=0;i<mp.size();i++)
        {
            v=mp[i];
            if(!e[u][v])
            {
                swap(mp[i],mp.back());
                mp.pop_back();
                --i;
                Q.push(v);
            }
        }
    }
    return cnt;
}

int main()
{
    int n,m,x,y;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)mp.push_back(i);
    for(int i=1; i<=m; i++)
    {
        scanf("%d%d",&x,&y);
        e[x][y]=1;
        e[y][x]=1;
    }
   while(!mp.empty())
   {
       int v=mp.back();
       mp.pop_back();
       int x=bfs(v);
       if(x)
       ans.push_back(x);
   }
   sort(ans.begin(),ans.end());
   printf("%d\n",ans.size());
   for(int i=0;i<ans.size();i++)
    printf("%d ",ans[i]);
   puts("");
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章