CF920E 补图强连通分量 BFS+set维护

题意:

http://codeforces.com/problemset/problem/920/E

给你一个补图,问原图有多少强连通分量,然后每个强连通分量有多少元素.

思路:

用set维护还可以更新的元素(也就是还没有访问的元素),用一个数组记录从该节点不能到达的地方,然后就可以为所欲为了.

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<set>
 4 #include<queue>
 5 #include<algorithm>
 6 using namespace std;
 7 const int MAXV=2e5+7;
 8 const int MAXE=4e5+7;
 9 struct edge{
10     int to,next;
11 }es[MAXE];
12 int tot,head[MAXV];
13 int V,E;
14 void init(){
15     tot=0;
16     memset(head,-1,sizeof(head));
17 }
18 void addEdge(int a,int b){
19     es[tot].to=b;
20     es[tot].next=head[a];
21     head[a]=tot++;
22 }
23 queue<int>q;
24 int mark[MAXV],visit[MAXV];
25 set<int>st;
26 int bfs(int now){
27     queue<int>q;while(!q.empty())q.pop();
28     q.push(now);
29     int cnt=0;
30     while(!q.empty()){
31         int u=q.front();q.pop();
32         if(!visit[u])++cnt;
33         else continue;
34         visit[u]=1;
35         for(int i=head[u];~i;i=es[i].next){
36             int v=es[i].to;
37             mark[v]=1;
38         }
39         for(auto i=st.begin();i!=st.end();){
40             if(!mark[*i]){
41                 q.push(*i);
42                 st.erase(i++);
43             }else{
44                 mark[*i]=0;
45                 i++;
46             }
47         }
48     }
49     return cnt;
50 }
51 int res[MAXV];
52 int main(){
53     scanf("%d%d",&V,&E);
54     init();
55     for(int i=0;i<E;++i){
56         int a,b;scanf("%d%d",&a,&b);
57         addEdge(a,b);
58         addEdge(b,a);
59     }
60     int k=0;
61     for(int i=1;i<=V;++i){
62         if(!visit[i])st.insert(i);
63     }
64     for(int i=1;i<=V;++i){
65         if(!visit[i]){
66             res[k++]=bfs(i);
67         }
68     }
69     printf("%d\n",k);
70     sort(res,res+k);
71     for(int i=0;i<k;++i){
72         printf("%d ",res[i]);
73     }
74     return 0;
75 }
View Code

 

posted on 2018-02-08 00:50  Na_OH  阅读(285)  评论(0编辑  收藏  举报

导航