hiho一下 第五十五周 连通性·四(无向图点双连通分量)

来源:互联网 发布:淘宝网页模板免费下载 编辑:程序博客网 时间:2024/05/01 05:14
#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int N=20010;const int M=202000;const int INF=0x7fffffff;struct edge{    int u,v,next;    int id;}edge[M];int group[M],mmin[M];int cnt,head[N];int belong[M];void addedge(int u,int v,int ii){    edge[cnt].u=u;edge[cnt].v=v;edge[cnt].next=head[u];    edge[cnt].id=ii;head[u]=cnt++;    edge[cnt].u=v;edge[cnt].v=u;edge[cnt].next=head[v];    edge[cnt].id=ii;head[v]=cnt++;}void init(int m){    cnt=0;    memset(head,-1,sizeof(head));        for(int i=1;i<=m;i++){        mmin[i]=INF;    }}struct Tarjan{//求点双连通分量模板    int col;int top,index;//col表示染色,id标记dfn,top为栈顶指针    int dfn[N],low[N],temp[M];    int Stack[M];    void init(){        memset(dfn, 0, sizeof(dfn));        memset(group,-1,sizeof(group));                top=0;col=0;index=0;    }    void tarjan(int u,int pre){                //初始化dfn[u]和low[u];        dfn[u]=low[u]=++index;        for(int i=head[u];i!=-1;i=edge[i].next){            int v=edge[i].v;            if(group[edge[i].id]!=-1)continue;            //节点v未被访问,则(u,v)为树边            if(!dfn[v]){                Stack[top++]=edge[i].id;//边进栈                tarjan(v,u);                low[u]=min(low[u],low[v]);                if(low[v]>=dfn[u])//子节点不可能到比u更早的节点,u是割点                {                    ++col;                    int k=edge[i].id;                    int minn=INF;                    do{                        k=Stack[--top];                        group[k]=col;                        if(k<minn)minn=k;                    }while(k!=edge[i].id);                    mmin[col]=minn;                }            }            else {                if(v!=pre){//回边                    Stack[top++]=edge[i].id;                    low[u]=min(low[u],dfn[v]);                }            }        }            }};Tarjan tj;int main(){    int n,m;    scanf("%d%d",&n,&m);    int u,v;    init(m);    for(int i=1;i<=m;i++){        scanf("%d%d",&u,&v);        addedge(u,v,i);    }    tj.init();    tj.tarjan(1,-1);    printf("%d\n",tj.col);    for(int i=1;i<=m;i++){        int aa=group[i];        printf("%d ",mmin[aa]);    }    printf("\n");    return 0;}

0 0