Connected Components? CodeForces
阿新 • • 發佈:2018-12-16
求補圖的各個連通塊大小 智商不夠 直接線段樹優化建圖 然後tarjan縮點 幸好記憶體不緊。。
#include <bits/stdc++.h> using namespace std; #define pb push_back const int maxn=2e5+10; const int maxm=2e5+10; const int N=0x3f3f3f3f; vector <int> edge[4*maxn]; vector <int> pre[maxn]; stack <int> stk; int first[4*maxn],val[4*maxn],dfn[4*maxn],low[4*maxn],belong[4*maxn],book[4*maxn],sum[4*maxn],mp[maxn],ans[maxn]; int n,m,nn,num,cnt,tot; void build(int l,int r,int cur) { int m; if(l==r) { val[cur]=1,mp[l]=cur; nn=max(nn,cur); return; } edge[cur].pb(2*cur); edge[cur].pb(2*cur+1); m=(l+r)/2; build(l,m,2*cur); build(m+1,r,2*cur+1); } void update(int tar,int pl,int pr,int l,int r,int cur) { int m; if(pl<=l&&r<=pr) { edge[tar].pb(cur); return; } m=(l+r)/2; if(pl<=m) update(tar,pl,pr,l,m,2*cur); if(pr>m) update(tar,pl,pr,m+1,r,2*cur+1); } void dfs(int cur) { int i,v,t; stk.push(cur); dfn[cur]=num,low[cur]=num,book[cur]=1; num++; for(i=0;i<edge[cur].size();i++) { v=edge[cur][i]; if(!dfn[v]) { dfs(v); low[cur]=min(low[cur],low[v]); } else if(book[v]) low[cur]=min(low[cur],low[v]); } if(dfn[cur]==low[cur]) { cnt++; while(!stk.empty()) { v=stk.top(); stk.pop(); book[v]=0; belong[v]=cnt; sum[cnt]+=val[v]; if(cur==v) break; } } } void tarjan() { int u,v; num=1,cnt=0; for(u=1;u<=nn;u++) if(!dfn[u]) dfs(u); } int main() { int i,u,v,a,b; scanf("%d%d",&n,&m); build(1,n,1); for(i=1;i<=m;i++) { scanf("%d%d",&u,&v); pre[u].pb(v),pre[v].pb(u); } for(u=1;u<=n;u++) { pre[u].pb(u),pre[u].pb(0),pre[u].pb(n+1); sort(pre[u].begin(),pre[u].end()); /* printf("***%d***\n",u); for(i=0;i<pre[u].size();i++) printf("%d ",pre[u][i]); printf("\n"); */ for(i=0;i+1<pre[u].size();i++) { a=pre[u][i],b=pre[u][i+1]; if(a+1<=b-1) update(mp[u],a+1,b-1,1,n,1); } } tarjan(); for(i=1;i<=cnt;i++) if(sum[i]!=0) ans[++tot]=sum[i]; sort(ans+1,ans+tot+1); printf("%d\n",tot); for(i=1;i<=tot;i++) printf("%d ",ans[i]); printf("\n"); return 0; } /* 5 6 1 3 1 4 1 5 2 4 2 5 3 5 5 7 1 3 1 4 1 5 2 4 2 5 3 4 3 5 */