題意:數組
http://codeforces.com/problemset/problem/920/Eide
給你一個補圖,問原圖有多少強連通份量,而後每一個強連通份量有多少元素.spa
思路:code
用set維護還能夠更新的元素(也就是尚未訪問的元素),用一個數組記錄從該節點不能到達的地方,而後就能夠隨心所欲了.blog
代碼:string
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 }