ZOJ2588:Burning Bridges(无向连通图求割边)

题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1588

吐下槽,不得不说ZOJ好坑,模版题做了一个多小时。

题意:
*        给出一个无向图,输入n(表示n个定点,1~n), m(m条边,有重边),
*        (2 <= N <= 10 000, 1 <= M <= 100 000),求这个无向图中的桥,
*        并输出桥属于输入中边的id.

     之前学图的连通性因为没看懂双连通分量,就把连通性的这些知识点搁置了,一直没有刷这方面的题,由于之前已经弄懂求桥的算法,所以看到题就直接上了,结果被一些

小错误给击败了,还好算法的思想没出问题,贴一下代码,以后当模版用。求桥:low[v]>dfn[u](u,v)为树枝边。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stack>
#define N 10010
using namespace std;
struct node
{
    int x,y,w,next,flag;
} eg[20*N];
int tt,head[N],dfn[N],low[N],ti,n,m,top;
int f[20*N];
void init()
{
    tt=0;
    ti=1;
    top=0;
    memset(head,-1,sizeof(head));
    memset(dfn,0,sizeof(dfn));
    memset(f,0,sizeof(f));
}
void add(int xx,int yy,int nu)
{
    for(int i=head[xx]; i!=-1; i=eg[i].next)//去重
    {
        if(eg[i].y==yy)
        {
            eg[i].flag=1;
            return ;
        }
    }
    eg[tt].x=xx;
    eg[tt].y=yy;
    eg[tt].w=nu;
    eg[tt].flag=0;
    eg[tt].next=head[xx];
    head[xx]=tt++;
}
void tarjan(int u,int fa)
{
    dfn[u]=low[u]=ti++;
    for(int i=head[u]; i!=-1; i=eg[i].next)
    {
        int v=eg[i].y;
        if(v==fa) continue;
        if(!dfn[v])
        {
            tarjan(v,u);
            low[u]=min(low[u],low[v]);
            if(low[v]>dfn[u]&&!eg[i].flag)
            {
                f[top++]=eg[i].w;
            }
        }
        else //无向图没有横跨边
        {
            low[u]=min(dfn[v],low[u]);
        }
    }
}
int main()
{
    int T,xx,yy;
    scanf("%d",&T);
    while(T--)
    {
        init();
        scanf("%d %d",&n,&m);
        for(int i=1; i<=m; i++)
        {
            scanf("%d %d",&xx,&yy);
            add(xx,yy,i);
            add(yy,xx,i);
        }
        tarjan(1,-1);
        int sum=0;
        for(int i=1; i<=m; i++)
        {
            if(f[i])
                sum++;
        }
        printf("%d\n",top);
        if(top)
        {
            sort(f,f+top);
            for(int i=0; i<top-1; i++)
            {
                printf("%d ",f[i]);
            }
            printf("%d\n",f[top-1]);
        }
        if(T!=0) printf("\n");
    }
    return 0;
}
//无向图是没有横边的

我不知道为什么这么写就PE

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stack>
#define N 10010
using namespace std;
struct node
{
    int x,y,w,next,flag;
}eg[20*N];
int tt,head[N],dfn[N],low[N],ti,n,m;
bool f[20*N];
void init()
{
    tt=0;
    ti=1;
    memset(head,-1,sizeof(head));
    memset(dfn,0,sizeof(dfn));
    memset(f,false,sizeof(f));
}
void add(int xx,int yy,int nu)
{
    for(int i=head[xx];i!=-1;i=eg[i].next)
    {
        if(eg[i].y==yy)
        {
            eg[i].flag=1;
            return ;
        }
    }
    eg[tt].x=xx;
    eg[tt].y=yy;
    eg[tt].w=nu;
    eg[tt].flag=0;
    eg[tt].next=head[xx];
    head[xx]=tt++;
}
void tarjan(int u,int fa)
{
    dfn[u]=low[u]=ti++;
    for(int i=head[u];i!=-1;i=eg[i].next)
    {
        int v=eg[i].y;
        if(v==fa) continue;
        if(!dfn[v])
        {
            tarjan(v,u);
            low[u]=min(low[u],low[v]);
            if(low[v]>dfn[u]&&!eg[i].flag)
            {
                f[eg[i].w]=true;
            }
        }
        else //无向图没有横跨边
        {
            low[u]=min(dfn[v],low[u]);
        }
    }
}
int main()
{
    int T,xx,yy;
    scanf("%d",&T);
    while(T--)
    {
        init();
        scanf("%d %d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d %d",&xx,&yy);
            add(xx,yy,i);
            add(yy,xx,i);
        }
        tarjan(1,-1);
        int sum=0;
        for(int i=1;i<=m;i++)
        {
            if(f[i])
                sum++;
        }
        printf("%d\n",sum);
        int F=1;
        for(int i=1;i<=m;i++)
        {
            if(f[i])
            {
                if(F)
                {
                    printf("%d",i);
                    F=0;
                }
                else printf(" %d",i);
            }
        }
        printf("\n");
        if(T!=0) printf("\n");
    }
    return 0;
}
//无向图是没有横边的
View Code

 

posted @ 2015-01-19 15:22  人艰不拆_zmc  阅读(313)  评论(1编辑  收藏  举报