poj2942解题报告

来源:互联网 发布:全职高手动画知乎 编辑:程序博客网 时间:2024/05/22 05:13

这道题其实就是求割点数量

用点双联通

#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 ; }


 

原创粉丝点击