zoj2588(无向图求割边)

这道题其实就是一道很简单的割边的模板题,不过需要处理重边导师意见有点麻烦的事

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int MAXN=20005;
const int MAXM=200005;
struct edge
{
    int to,next,id,num;//这个地方需要在原有模板的基础上加上id(边的标号)和num(是否为重边)
    bool cut;
} edge[MAXM];
int ans[MAXM];
int head[MAXN],tot;
int low[MAXN],dfn[MAXN],Stack[MAXN];
int Index,top;
bool Instack[MAXN];
bool cut[MAXN];
int add_block[MAXN];
int bridge;
int T,a,b;
long long n,m;
void addedge(int u,int v,int x,int num)//我在传递四个值的时候对了,不传递num的时候没有处理好
{
    edge[tot].to=v;
    edge[tot].next=head[u];
    edge[tot].cut=false;
    edge[tot].id=x;
    edge[tot].num=num;
    head[u]=tot++;
}
void tarjan(int u,int pre)
{
    int v,k=1;
    low[u]=dfn[u]=++Index;
    Stack[top++]=u;
    Instack[u]=true;
    int son=0,sum=0;
    for(int i=head[u]; i!=-1; i=edge[i].next)
    {
        v=edge[i].to;
        if(v==pre)
            continue;
        if(!dfn[v])
        {
            son++;
            tarjan(v,u);
            if(low[u]>low[v])
                low[u]=low[v];
            if(low[v]>dfn[u]&&edge[i].num!=1)
            {
                bridge++;
                edge[i].cut=true;
                edge[i^1].cut=true;
                ans[bridge]=edge[i].id;//这里直接是边的标号
            }
        }
        else if(low[u]>dfn[v])
            low[u]=dfn[v];
    }
    if(u==pre)
        add_block[u]=son-1;
    Instack[u]=false;
    top--;
}
void init()
{
    tot=0;
    bridge=0;
    Index=0;
    memset(low,0,sizeof(low));
    memset(dfn,0,sizeof(dfn));
    memset(Instack,0,sizeof(Instack));
    memset(add_block,0,sizeof(add_block));
    memset(edge,-1,sizeof(edge));
    memset(head,-1,sizeof(head));
    memset(ans,0,sizeof(ans));
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>T;
    while(T--)
    {
        init();
        cin>>n>>m;
        for(int i=1; i<=m; i++)
        {
            cin>>a>>b;
            for(int j=head[a]; j!=-1; j=edge[j].next)
                if(edge[j].to==b)
                {
                    edge[i].num=1;
                }
            addedge(a,b,i,edge[i].num);
            addedge(b,a,i,edge[i].num);
        }
        for(int i=1; i<=n; i++)
        {
                tarjan(i,i);
        }
        cout<<bridge<<endl;//对输出进行处理的时候,首先需要考虑输出空行的问题,然后还需要需要考虑没有桥的时候,在这里吃了好大的亏,一直WA到死
        sort(ans+1,ans+bridge+1);
        for(int i=1,u=bridge; i<=bridge; i++)
         {
              cout<<ans[i];
              if(--u)
                cout<<" ";
         }
        if(bridge)
            cout<<endl;
            if(T)
                cout<<endl;
    }
    return 0;
}

你可能感兴趣的:(图论,连通)