题目的意思是要我们去掉最多的边使图还是连通的,同了强连通分支的算法。如下:
#include <stdio.h>

const int LEN = 5005;

struct HEAD 
{
    
int state; //搜索状态
    int fa; //在堆栈中的位置
    int du;
    
int next;
    
int last;
}
;
HEAD head1[LEN]; 
//原图
HEAD head2[LEN]; //新图

struct NODE
{
    
int num;
    
int other; //记录还有一条边的位置
    int used; //是否可用
    int next;
}
node[LEN*8];
int next_n;

int bridge[LEN/2]; //记录桥的位置
int next_b; 

void init_m ( HEAD head[], int n )
{

    
for ( int i=0; i<n; i++ )
    
{
        head[i].state 
= 0;
        head[i].next 
= -1;
        head[i].du 
= 0;
    }

}


inline 
void ins ( HEAD head[], int a, int b )
{

    node[next_n].next 
= -1;
    node[next_n].num 
= b;
    next_n 
++;

    
if ( head[a].next==-1 )
        head[a].next 
= next_n-1;
    
else
        node[ head[a].last ].next 
= next_n-1;
    head[a].last 
= next_n-1;
    head[a].du 
++;
}


int ser ( HEAD head[], int far, int p, int depth ) //找桥
{

    head[p].state 
= 1;

    
int fa = depth;
    head[p].fa 
= depth;
    
for ( int i=head[p].next; i!=-1; i=node[i].next  )
    
{
        
int e = node[i].num;
        
if ( head[e].state==1&&e!=far )
        
{
            
if ( fa>head[e].fa )
                fa 
= head[e].fa;
        }

        
else if ( head[e].state==0 )
        
{
            
int sonfa = ser ( head, p, e, depth+1 );
            
if ( sonfa>depth )
                bridge[next_b
++= i;
            
if ( fa>sonfa )
                fa 
= sonfa;
        }

    }

    head[p].state 
= 2;

    
return fa;
}


void ser2 ( HEAD head[], int p, int color )
{

    head[p].state 
= 1;

    head[p].fa 
= color;
    
for ( int i=head[p].next; i!=-1; i=node[i].next )
    
{
        
int e = node[i].num;
        
if ( !node[i].used&&!head[e].state )
            ser2 ( head, e, color );
    }


    head[p].state 
= 2;
}


int work ( int n )
{

    
//找桥
    next_b = 0;
    ser ( head1, 
-100 );
    
for ( int i=0; i<next_b; i++ )
    
{
        
int p = bridge[i];
        node[p].used 
= 1;
        node[ node[p].other ].used 
= 1;
    }

    
//求连通分块
    for ( int i=0; i<n; i++ )
        head1[i].state 
= 0;
    
int color = 0;
    
for ( int i=0; i<n; i++ )
    
{
        
if ( !head1[i].state )
            ser2 ( head1, i, color
++ );
    }

    
//建图
    init_m ( head2, color );
    
for ( int i=0; i<n; i++ )
        
for ( int j=head1[i].next; j!=-1; j=node[j].next )
        
{
            
int a = i;
            
int b = node[j].num;
            
if ( head1[a].fa!=head1[b].fa )
            
{
                ins ( head2, head1[a].fa, head1[b].fa );
            }

        }

    
int ans = 0;
    
for ( int i=0; i<color; i++ )
    
{
        
if ( head2[i].du==1 )
            ans 
++;
    }

    
return (ans+1)/2;
}


int main ()
{

    
int n, m;
    scanf ( 
"%d%d"&n, &m );
    next_n 
= 0;
    init_m ( head1, n );
    
for ( int i=0; i<m; i++ )
    
{
        
int a, b;
        scanf ( 
"%d%d"&a, &b );
        ins ( head1, a
-1, b-1 );
        node[next_n
-1].other = next_n;
        ins ( head1, b
-1, a-1 );
        node[next_n
-1].other = next_n-2;
    }


    printf ( 
"%d\n", work ( n ) );
    
return 0;
}