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;
}

 

posted on 2016-06-09 14:37  恶devil魔  阅读(139)  评论(0编辑  收藏  举报

导航