pku2942 Knights of the Round Table

#include  < iostream >
#include 
< stack >
#include 
< algorithm >
using   namespace  std;

#define  MAXN 1001
#define  min(a,b) (a<b?a:b)

typedef pair
< int , int >  PAIR;

int  p[MAXN],ecnt,n,m,dfn[MAXN],lowlink[MAXN],sign,st,color[MAXN];
bool  hate[MAXN][MAXN],mark[MAXN],ans[MAXN];
stack
< PAIR >  sta;

struct  Edge{
    
int  v,next;
}edg[MAXN
* MAXN];


void  init(){
    ecnt
= 0 ;
    memset(p,
- 1 , sizeof (p));
    memset(dfn,
- 1 , sizeof (dfn));
    memset(hate,
false , sizeof (hate));
    sign
= 0 ;
    
while ( ! sta.empty())
        sta.pop();
    memset(ans,
false , sizeof (ans));
}

bool  check_odd( int  u, int  col){ // 检查该子块是否为二分图
     int  i,v;
    color[u]
= col;
    
for (i = p[u];i !=- 1 ;i = edg[i].next){
        v
= edg[i].v;
        
if (mark[v]){
            
if (color[v] == 0 ){
                
if (check_odd(v, - col))
                    
return   true ;
            }
            
else   if (col == color[v])
                
return   true ;
        }
    }
    
return   false ;
}


void  dfs( int  pre, int  u){
    
int  i,j,v,x,y;
    PAIR P;
    dfn[u]
= lowlink[u] =++ sign;
    
for (i = p[u];i !=- 1 ;i = edg[i].next){
        v
= edg[i].v;
        
if (v != pre  &&  dfn[u] > dfn[v]){ // 边u-v未访问过
            sta.push(make_pair(u,v));
        }
        
if (dfn[v] ==- 1 ){ // 顶点v未访问过
            dfs(u,v);
            lowlink[u]
= min(lowlink[u],lowlink[v]);
            
if (dfn[u] <= lowlink[v]){ // u是割点,找到一个重连通分量
                memset(mark, false , sizeof (mark));
                st
= u;
                    
                
do {
                    P
= sta.top();
                    x
= P.first;
                    y
= P.second;
                    sta.pop();
                    mark[x]
= mark[y] = true ;
                }
while ( ! ( (x == &&  y == v)  ||  (x == &&  y == u) ));

                memset(color,
0 , sizeof (color));
                
if (check_odd(st, 1 )){
                    
for (j = 1 ;j <= n;j ++ )
                        ans[j]
|= mark[j];
                }
            }
        }
        
else   if (v != pre){
            lowlink[u]
= min(lowlink[u],dfn[v]);
        }
    }
}

int  solve(){
    
int  i,anscnt = 0 ;
    
for (i = 1 ;i <= n;i ++ ){
        
if (dfn[i] ==- 1 ){
            dfs(
- 1 ,i);
        }
    }
    
for (i = 1 ;i <= n;i ++ )
        
if (ans[i])
            anscnt
++ ;
    
return  n - anscnt;
}


int  main(){
    
int  i,u,v;
    
while (scanf( " %d%d " , & n, & m)  &&  n  &&  m){
        init();
        
for (i = 0 ;i < m;i ++ ){
            scanf(
" %d%d " , & u, & v);
            hate[u][v]
= hate[v][u] = true ;
        }
        
for (u = 1 ;u <= n;u ++ ){
            
for (v = u + 1 ;v <= n;v ++ ){
                
if ( ! hate[u][v]){
                     edg[ecnt].v
= v;
                     edg[ecnt].next
= p[u];
                     p[u]
= ecnt ++ ;
                     edg[ecnt].v
= u;
                     edg[ecnt].next
= p[v];
                    p[v]
= ecnt ++ ;
                }
            }
        }


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


你可能感兴趣的:(table)