HDU 3394 Railway 无向图的桥与点-双连通

来源:互联网 发布:海城市教育局网通知 编辑:程序博客网 时间:2024/06/07 09:06

题目大意:给一个无自环无重边的图。如果一条边不在任何简单环上,是一类边;如果一条边在两个或以上简单环上,是另一类边。求图中这两类的边的个数。

思路:第一类边即是桥,关键是第二类边怎么求。在一个点-双连通集团中,边的个数>点的个数,那么每条边都在至少两个环上。

//#pragma comment(linker, "/STACK:102400000,102400000")#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<cmath>#include<cctype>#include<string>#include<algorithm>#include<iostream>#include<ctime>#include<map>#include<set>using namespace std;#define MP(x,y) make_pair((x),(y))#define PB(x) push_back(x)typedef __int64 LL;//typedef unsigned __int64 ULL;/* ****************** */const int INF=100011122;const double INFF=1e100;const double eps=1e-8;const int mod=9999991;const int NN=10005;const int MM=100010*2;/* ****************** */struct G{    int u,v,next;}E[MM];int p[NN],T;int dfn[NN],low[NN],tsp;int sta[MM],sta_top;int id[NN],id_cnt;int qiao,ans;void add(int u,int v){    E[T].u=u;    E[T].v=v;    E[T].next=p[u];    p[u]=T++;}void bcc(int u,int fa){    int i,v;    int dian,bian,ii;    dfn[u]=low[u]=++tsp;    for(i=p[u];i+1;i=E[i].next)    {        v=E[i].v;        if(dfn[v]==0)        {            sta[++sta_top]=i;            bcc(v,u);            low[u]=min(low[u],low[v]);            if(low[v]>dfn[u])                qiao++;            if(low[v]>=dfn[u])            {                dian=0;                bian=0;                id_cnt++;                for(;;)                {                    ii=sta[sta_top--];                    bian++;                    if(id[E[ii].u]!=id_cnt)                    {                        id[E[ii].u]=id_cnt;                        dian++;                    }                    if(id[E[ii].v]!=id_cnt)                    {                        id[E[ii].v]=id_cnt;                        dian++;                    }                    if(E[ii].u==u && E[ii].v==v)                        break;                }                if(bian>dian)                    ans+=bian;            }        }        else if(dfn[v]<dfn[u] && v!=fa)        {            sta[++sta_top]=i;            low[u]=min(low[u],dfn[v]);        }    }}int main(){    int n,m;    int u,v,i;    while(scanf("%d%d",&n,&m)!=EOF)    {        if(n==0 && m==0)            break;        memset(p,-1,sizeof(p));        T=0;        while(m--)        {            scanf("%d%d",&u,&v);            add(u,v);            add(v,u);        }        tsp=0;        sta_top=0;        id_cnt=0;        for(i=0;i<n;i++)        {            dfn[i]=low[i]=0;            id[i]=-1;        }        qiao=ans=0;        for(i=0;i<n;i++)        {            if(dfn[i]==0)                bcc(i,-1);        }        printf("%d %d\n",qiao,ans);    }    return 0;}


0 0