新姿势 bfs+链表求反图
/************************************************************** Problem: 1098 User: lxy8584099 Language: C++ Result: Accepted Time:8220 ms Memory:34596 kb ****************************************************************/ /* 没有联系的要在一起 所以就是反图 缩点 不过n好大。。。反图建不起来 学到新的姿势 bfs+链表 求出反边 只要与u不相连的v 一定在同一层 今天最后一题。。。满足每日三题2333 */ #include<bits/stdc++.h> using namespace std; const int N=100050,M=2000050; struct road {int v,nxt;} e[M<<1]; int head[N],n,m,tot=1,sta[N],ans; int pre[N],nxt[N],q[N],top; bool vis[N]; void add(int u,int v) {e[++tot].nxt=head[u];head[u]=tot;e[tot].v=v;} void cut(int x) {nxt[pre[x]]=nxt[x],pre[nxt[x]]=pre[x];} void bfs(int x) { int l=0,r=1; q[0]=x; while(l<r) { sta[ans]++; int u=q[l++]; for(int j=head[u];j;j=e[j].nxt) vis[e[j].v]=1; // 打标记 for(int i=nxt[0];i<=n;i=nxt[i]) if(!vis[i]) // 没有边的一定在一起 cut(i),q[r++]=i; for(int j=head[u];j;j=e[j].nxt) vis[e[j].v]=0; // 还原标记 } } int main() { scanf("%d%d",&n,&m); for(int i=1,u,v;i<=m;i++) { scanf("%d%d",&u,&v); add(u,v);add(v,u); } for(int i=0;i<=n;i++) nxt[i]=i+1; for(int i=1;i<=n+1;i++) pre[i]=i-1; for(int i=nxt[0];i<=n;i=nxt[0]) cut(i),ans++,bfs(i); printf("%d\n",ans); sort(sta+1,sta+ans+1); for(int i=1;i<=ans;i++) printf("%d ",sta[i]);printf("\n"); return 0; }