zoj 2588 Burning Bridges(求割边+对重边的处理)

题目链接:

点击打开链接

题目大意:

求出割边的数目和编号

题目分析:

模板题,注意对重边的处理即可

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#define N 10007
#define M 100007

using namespace std;

struct Edge
{
    int v,next,id,tag;
}e[M<<2];

int cc,head[N];

void add ( int u , int v , int id )
{
    int i;
    for ( i = head[u] ; ~i ; i = e[i].next )
        if ( e[i].v == v ) break;
    if ( ~i )
    {
        e[i].tag = 1;
        e[i].tag = 1;
        return;
    }
    e[cc].v = v;
    e[cc].next = head[u];
    e[cc].id = id;
    e[cc].tag = 0;
    head[u] = cc++;
}

vector<int> ans;
int dfn[N],low[N],times;

void tarjan ( int u , int p )
{
    dfn[u] = low[u] = ++times;
    for ( int i = head[u] ; ~i ; i = e[i].next )
    {
        int v = e[i].v;
        if ( !dfn[v] )
        {
            tarjan(v,u);
            low[u] = min ( low[u] , low[v] );
            if ( low[v] > dfn[u] && !e[i].tag )
                ans.push_back ( e[i].id );
        }
        else if ( v != p )
            low[u] = min ( low[u] , dfn[v] );
    }
}

int t,n,m,u,v;

int main ()
{
    scanf ( "%d" , &t );
    while ( t-- )
    {
        ans.clear();
        cc = times = 0;
        memset ( head , -1, sizeof(head));
        memset ( dfn , 0 , sizeof ( dfn ));

        scanf ( "%d%d" , &n , &m );

        for ( int i = 1 ; i <= m ; i++ )
        {
            scanf ( "%d%d" , &u , &v );
            add ( u , v , i );
            add ( v , u , i );
        }

        for ( int i = 1 ; i <= n ; i++ )
            if ( !dfn[i] )
                tarjan(i,-1);

        printf ( "%d\n" , ans.size());
        if ( ans.size())
        {
            sort ( ans.begin() , ans.end());
            printf ( "%d" , ans[0] );
            for ( int i = 1 ; i < ans.size() ; i++ )
                printf ( " %d" , ans[i] );
            puts("");
        }
        if (t) puts("");
    }
}


你可能感兴趣的:(C++,图论,割边)