边双联通及其缩点

来源:互联网 发布:ps软件下载后打不开 编辑:程序博客网 时间:2024/05/20 09:27
    #include <iostream>    #include <cstdio>    #include <cstring>    #include <queue>    #include <algorithm>    #include <cmath>    #define LL long long    using namespace std;    const int maxm=1000*2+10;    const int maxn=1000+10;    struct node    {        int u,v,next;    };    int is_edge[maxm],n,m;    node e[maxm];    int head[maxn],vis[maxn],tot,pre[maxn],low[maxn],dfs_clock,ans,tot2;    int degree[maxn];    void dfs(int fa,int u,int en)    {        low[u]=pre[u]=++dfs_clock;        int i,v;        for(i=head[u];i!=-1;i=e[i].next)        {            v=e[i].v;            if(!pre[v])            {                dfs(u,v,i);                low[u]=min(low[u],low[v]);                if(low[v]>=pre[v]) {  is_edge[i]=is_edge[i^1]=1;}            }            else            {                if(pre[v]<pre[u]&&(i^1)!=en)                    low[u]=min(low[u],pre[v]);            }        }    }    void addedge(int u,int v)    {        e[tot].u=u; e[tot].v=v; e[tot].next=head[u];        head[u]=tot++;        e[tot].u=v; e[tot].v=u; e[tot].next=head[v];        head[v]=tot++;    }    void Init()    {        int i;        memset(head,-1,sizeof(head));        memset(degree,0,sizeof(degree));        memset(is_edge,0,sizeof(is_edge));        memset(pre,0,sizeof(pre));        memset(vis,0,sizeof(vis));    }    void shrink_node(int u,int num)    {        int i,v,mark;        for(i=head[u];i!=-1;i=e[i].next)        {            v=e[i].v;            if(!vis[v])            {                vis[v]=1;                if(is_edge[i])                {                    degree[num]++;                    mark=++tot2;                    degree[mark]++;                    shrink_node(v,mark);                }                else shrink_node(v,num);            }        }    }    int main()    {        int cas=0;        while(~scanf("%d%d",&n,&m))        {            if(!n&&!m) break;            tot=0;            Init();            int u,v,i;            for(i=0;i<m;i++)            {                scanf("%d%d",&u,&v);                addedge(u,v);            }            int p1,p2;            dfs_clock=0;            ans=0;            dfs(-1,1,-1);            tot2=1;            shrink_node(1,1);            for(i=1;i<=tot2;i++) if(degree[i]==1) ans++;            ans=(ans+1)/2;            printf("%d\n",ans);        }        return 0;    }

原创粉丝点击