hihocoder1184 连通性二·边的双连通分量
输入
第1行:2个正整数,N,M。表示点的数量N,边的数量M。1≤N≤20,000, 1≤M≤100,000
第2..M+1行:2个正整数,u,v。表示存在一条边(u,v),连接了u,v两台服务器。1≤u<v≤N
保证输入所有点之间至少有一条连通路径。
输出
第1行:1个整数,表示该网络的服务器组数。
第2行:N个整数,第i个数表示第i个服务器所属组内,编号最小的服务器的编号。比如分为{1,2,3},{4,5,6},则输出{1,1,1,4,4,4};若分为{1,4,5},{2,3,6}则输出{1,2,2,1,1,2}
/* *********************************************** Author :devil Created Time :2016/6/9 14:37:52 ************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <stdlib.h> using namespace std; const int N=20010; int dfn[N],low[N],f[N],Stack[N],belong[N],cou=1,ed=0,ans=0; vector<int>eg[N]; void dfs(int u) { int v; dfn[u]=low[u]=cou++; Stack[ed++]=u; for(int i=0;i<eg[u].size();i++) { v=eg[u][i]; if(!dfn[v]) { f[v]=u; dfs(v); low[u]=min(low[u],low[v]); } else if(v!=f[u]) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { ans++; int tmp=ed-1; while(Stack[tmp]!=u) tmp--; int minp=*min_element(Stack+tmp,Stack+ed); do { v=Stack[--ed]; belong[v]=minp; }while(u!=v); } } int main() { //freopen("in.txt","r",stdin); int n,m,u,v; scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { scanf("%d%d",&u,&v); eg[u].push_back(v); eg[v].push_back(u); } dfs(1); printf("%d\n",ans); for(int i=1;i<=n;i++) printf("%d ",belong[i]); return 0; }