zoukankan      html  css  js  c++  java
  • poj 2942 Knights of the Round Table(点双连通)

    题意:亚瑟王座下有N个骑士,他们要坐在一张圆桌上议会,但是你知道,骑士的脾气总是很暴躁的,如果相邻的两个骑士的意见不同,他们就会动用武力,亚瑟王为了使议会顺利进行,要求巫师梅林设计一种方案,使任意两个互相讨厌的骑士都不坐在一起,圆桌上的人必须是奇数个,因为他也许会为一个问题进行投票,不希望出现票数相等的情况,当然也不能只有一个人,因为一个人根本不用开什么会议嘛,给出互相讨厌的骑士的连接关系,最后不能参加会议的骑士就会被开除,现在亚瑟王想知道最少要开除多少骑士。

    思路:建图很简单,就是给出的连接图的补图,求强连通分量也很容易想到,以为任意个强连通分量中的两个人都不是互相讨厌的,但是对于人数必须的奇数个,这就有点难想到了,我也只是想到了求强连通分支这个地方,后面的参考了一下解题报告,有个定理是:点双连通分量中存在奇圈,那么这个分量中所有的点都可以出现在奇圈上,这样的话,在求完强连通分支后,就在每个分支中找是否有奇环,如果有的话那么这个分支中的所有人都可以参加会议。至于求奇环,也是参照报告中的二分图的染色来求的。

    代码:

    View Code
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <stack>
    #include <math.h>
    #define  N 1005
    using namespace std ;
    
    bool map[N][N] ;
    int dfn[N] , low[N] , used[N] , vist[N] , mark[N] ;
    int n , m , ans , id ;
    stack<int>p;
    int a[N] ;
    
    //用二分图染色的方法判断奇环
    bool IsOk( int x , int w )
    {
        vist[x] = w ;
        for ( int i = 1 ; i <= n ; i++ )
        if ( map[x][i] )
        {
            if ( used[i] )
            {
                if ( vist[x] == vist[i] )//若有两个相邻的点同色,则存在奇环,返回true
                return true ;
                if ( vist[i] == -1 )
                IsOk( i , w ^ 1 ) ;
            }
        }
        return false ;
    }
    
    void jud ( int s )
    {
        int i ;
        memset( used , 0 , sizeof ( used )) ;
        //标记该分支中的点
        for ( i = 0 ; i < s ; i++ )
        {
            used[a[i]] = 1 ;
        }
        
        //判断是否有奇环
        for ( i = 0 ; i < s ; i++ )
        {
            memset( vist , -1 , sizeof ( vist )) ;
            if ( IsOk( a[i] , 1 ))
            break ;
        }
        
        //如果有奇环则将该分支中的点加起来
        if ( i < s )
        {
            for ( i = 0 ; i < s ; i++ )
            if ( !mark[a[i]] )
            {
                ans++ ;
                mark[a[i]] = 1 ;
            }
        }
    }
    
    void dfs( int x )
    {
        dfn[x] = low[x] = ++id ;
        p.push( x ) ;
        for( int i = 1 ; i <= n ; i++ )
        {
            if ( map[x][i] )
            {
                if ( !dfn[i] )
                {
                    dfs( i ) ;
                    low[x] = min ( low[x] , low[i] ) ;
                    if ( low[i] >= dfn[x] )//点x是割点,
                    {
                        //将该分支中的点出栈,x留在栈中。
                        a[0] = x ;
                        int k = 1 , u ;
                        do
                        {
                            u = p.top();
                            p.pop();
                            a[k++] = u ;
                        }while( u != i ) ;
                        
                        //判断该分支中是否有奇环
                        jud( k ) ;
                    }
                }
                else if ( low[x] > dfn[i] )
                low[x] = dfn[i] ;
            }
        }
    }
    
    int main()
    {
        int i , x , y ;
    
        while ( scanf ( "%d%d" , &n , &m ) , n + m )
        {
            //建图
            memset( map , true , sizeof( map )) ;
            for ( i = 1 ; i <= m ; i++ )
            {
                scanf ( "%d%d" , &x , &y ) ;
                map[x][y] = map[y][x] = false ;
            }
            for( i = 1 ; i <= n ; i++ )
            {
                map[i][i] = false ;
                dfn[i] = low[i] = mark[i] = 0 ;
            }
            
            //求强连通分支
            ans = id = 0 ;
            for ( i = 1 ; i <= n ; i++ )
            if( !dfn[i] )
            dfs( i ) ;
    
            printf ( "%d\n" , n - ans ) ;
        }
    
        return 0 ;
    }

     

  • 相关阅读:
    简介.Net对象序列化.txt
    如何在Web页面退出前提示用户保存数据?
    如何将图片存储到数据库中
    页面回车键响应,onkeydown事件
    用C#创建Windows服务(Windows Services)
    解决“Visual Studio 要求设计器使用文件中的第一个类。移动类代码使之成为文件中的第一个类,然后尝试重新加载设计器。”方法
    动态创建htm元素并添加到document中
    如何在Asp.net的Header中添加/title/Meta tages/CSS
    无法打开项目文件,“d:\web\webapp.csproj”,此安装不支持该项目类型
    用Intelligencia.UrlRewriter实现URL重写
  • 原文地址:https://www.cnblogs.com/misty1/p/2768390.html
Copyright © 2011-2022 走看看