您的位置:首页 > 其它

poj 2942 LA3523  点-双…

2013-12-14 20:02 232 查看
这个题目的意思是:有一些骑士 , 需要开圆桌会议 , 但有一些骑士不能坐在一起 , 问最少有多少个骑士不能参加任何一个会议


注意:  不是开一次会议 , 而是开很多次会议 , 每次会议至少3个人 ,
问有哪些骑士是任何一次都不能参加的 , 一个骑士可以参加多个会议。

这是一个无向点-双连通子图的问题 , 先把所有Bcc都求出来 , 然后判断那些bcc中的骑士超过3个人 , 并且人数奇数 , 对于判断
, 可以用判断一个图存不存在奇环 , 对于奇环 ,
我们用交叉染色搜索奇圈的方法来判断当前双连通分量中是否存在奇圈  , 如果双连通分量中存在奇圈 ,
那么我们就能确定 , 这个双连通分量中的所有骑士都能被安排坐下 , 因为如果这个双连通分量有偶数骑士 , 并且存在一个奇圈 ,
那么我们确定肯定存在其他奇圈 , 如果这个双连通分量有奇数个骑士, 那么肯定存在一个环包含这个双连通分量中的所有骑士。

代码:

#include

#include

#include

#include

#include

using namespace std;

const int MAXN = 1010 ;

int pre[MAXN] , iscut[MAXN] , bccno[MAXN] , dfs_clock ,
bcc_cnt;

int n , m;

int A[MAXN][MAXN] ;

int color[MAXN] ;

vectorgrap[MAXN] , bcc[MAXN];

stacks , t;

int dfs(int u ,int fu)

{

    int lowu =
pre[u] = ++dfs_clock;

    int child =
0;

    for(int i =
0 ; i < grap[u].size() ; i++)

    {

   
    int v =
grap[u][i];

   
   
if(!pre[v])

   
    {

   
   
   
s.push(u);

   
   
   
t.push(v);

   
   
    child +=
1;

   
   
    int lowv =
dfs(v , u);

   
   
    if(lowu
> lowv)  lowu = lowv;

   
   
    if(lowv
>= pre[u]) 

   
   
    {

   
   
   
    iscut[u] =
true ;

   
   
   
   
bcc_cnt++; 
bcc[bcc_cnt].clear();  // 清空

   
   
   
    for(;
;)

   
   
   
    {

   
   
   
   
    int x =
s.top() , y = t.top();

   
   
   
   
    s.pop() ;
t.pop();

   
   
   
   
    if(bccno[x]
!= bcc_cnt)  {bcc[bcc_cnt].push_back(x) ; bccno[x]
= bcc_cnt;}

   
   
   
   
    if(bccno[y]
!= bcc_cnt)  {bcc[bcc_cnt].push_back(y) ; bccno[y]
= bcc_cnt;}

   
   
   
   
    if(x == u
&& y ==
v)   break;

   
   
   
    }

   
   
    }

   
    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: