这道题其实就是求割点数量
用点双联通
#include <iostream>
#include <cstring>
#include <cstdio>
#include <stack>
using namespace std ;
const int MAXN = 1001 ;
const int MAXM = 2*MAXN * MAXN ;
const int INF = 99999999 ;
struct type
{
int end , next ;
} ;
type edge[MAXM] ;
int head[MAXN] , Count , map[MAXN][MAXN] , vis[MAXN] , visit[MAXN] , low[MAXN] , dfn[MAXN] ;
int color[MAXN] , belone[MAXN] , val[MAXN] , ans , cnt , Time , flag ;
stack < int > S ;
void addedge( int start , int end )
{
edge[Count].end = end ;
edge[Count].next = head[start] ;
head[start] = Count ++ ;
}
void dfs( int root , int col )
{
int i , end ;
color[root] = col ;
for( i = head[root] ; i != -1 ; i = edge[i].next )
{
end = edge[i].end ;
if( belone[end] != cnt ) continue ;
if( color[end] == 1 - col ) continue ;
if( color[end] == -1 ) dfs( end , 1 - col ) ;
else if( color[end] == col ) flag = 1 ;
if( flag ) return ;
}
}
void tarjan_dfs( int cur , int father )
{
S.push( cur ) ;
dfn[cur] = low[cur] = Time ++ ;
visit[cur] = 1 ;
for( int i = head[cur] ; i != -1 ; i = edge[i].next )
{
int end = edge[i].end ;
if( end == father ) continue ;
if( !visit[end] )
{
tarjan_dfs( end , cur ) ;
low[cur] = min( low[cur] , low[end] ) ;
if( low[end] >= dfn[cur] )
{
int ss ;
cnt ++ ;
ans = 0 ;
do
{
ss = S.top() ;
S.pop() ;
val[++ans] = ss ;
belone[ss] = cnt ;
}while( ss != end ) ;
belone[cur] = cnt ;
val[++ans] = cur ;
flag = 0 ;
memset( color , -1 , sizeof( color ) ) ;
dfs( cur , 0 ) ;
if( flag ) for( int j = 1 ; j <= ans ; j ++ )
vis[val[j]] = 1 ;
}
}
else low[cur] = min( low[cur] , dfn[end] ) ;
}
}
int main()
{
int n , m , i , j , temp , sum ;
while( scanf( "%d%d" , & n , & m ) != EOF && n && m )
{
memset( head , -1 , sizeof( head ) ) ;
memset( map , 0 , sizeof( map ) ) ;
Count = 0 ;
while( m -- )
{
int start , end ;
scanf( "%d%d" , & start , & end ) ;
map[start][end] = map[end][start] = 1 ;
}
for( i = 1 ; i <= n ; i ++ )
for( j = i + 1 ; j <= n ; j ++ )
if( ! map[i][j] ){
addedge( i , j ) ;
addedge( j , i ) ;
}
cnt = 0 ; Time = 0 ;
memset( vis , 0 , sizeof( vis ) ) ;
memset( visit , 0 , sizeof( visit ) ) ;
memset( belone , -1 , sizeof( belone ) ) ;
for( int i = 1 ; i <= n ; i ++ )
if( ! visit[i] ) tarjan_dfs( i , -1 ) ;
sum = 0 ;
for( int i = 1 ; i <= n ; i ++ )
if( vis[i] ) sum ++ ;
printf( "%d\n" , n - sum ) ;
}
return 0 ;
}