您的位置:首页 > 其它

hihocoder1184 连通性二·边的双连通分量

2016-06-09 14:37 344 查看

输入

第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
,low
,f
,Stack
,belong
,cou=1,ed=0,ans=0;
vector<int>eg
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: