cf920e(链表优化bfs)

求反图联通块,由于反图边太多,直接暴力行不通。。。然后陷入沉思。。

标解算是比较少见的算法了吧。。

枚举每个点,和平常一样bfs找联通的点,不一样的是在找点时要先标记不连通的之后再找。。

然后这样复杂度是 O(n^2)还是不行。。

所以用链表优化,储存当前还没有找到联通块的点,由于原图边非常少,联通块不会很多,所以基本上找到第两三个联通块链表中的点就剩不了多少了。。

这里的链表尝试用了一下list容器。。写起来比较方便。。





#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<list>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define eps 1e-8
#define inf 1e9
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define succ(x) (1<<x)
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define ls T[i<<1]
#define rs T[i<<1|1]
#define op T[i]
#define mid (x+y>>1)
#define NM 1000005
#define nm 400005
#define pi 3.141592653
using namespace std;
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}






int n,m,_x,_y,ans[NM],cnt;
bool c[NM],v[NM];
queue<int >q;
struct edge{int t;edge*next;}e[nm],*h[NM],*o=e;
void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;}

list<int >b;
int bfs(int x){
	int s=0;q.push(x);v[x]++;
	while(!q.empty()){
		int t=q.front();q.pop();
		link(t)c[j->t]=true;
		for(auto it=b.begin();it!=b.end();)
			if(!c[*it])q.push(*it),v[*it]++,s++,b.erase(it++);
			else it++;
		link(t)c[j->t]=false;
	}
	return s;
}


int main(){
	n=read();m=read();
	inc(i,1,n)b.push_back(i);
	inc(i,1,m){_x=read();_y=read();add(_x,_y);add(_y,_x);}
	inc(i,1,n)if(!v[i])ans[++cnt]=bfs(i);
	sort(ans+1,ans+1+cnt);
	printf("%d\n",cnt);
	inc(i,1,cnt-1)printf("%d ",ans[i]);printf("%d\n",ans[cnt]);
	return 0;
}




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

Example
Input
5 5
1 2
3 4
3 2
4 2
2 5
Output
2
1 4 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值