您的位置:首页 > 其它

LA 5135 Mining Your Own Business

2013-12-14 20:02 316 查看
这是一个bcc题目 。

建图模型是:在一个无向图上 , 选择尽量少的点涂黑 , 使得任意删除一个点 , 每个连通分量都至少有一个黑点 。

所有 ,  可以发现 , 如果把割点涂黑是不划算的 。 因此有两种方法。

1、用dfs求出所以割点 , 然后再用bfs进行遍历(不能经过割点) , 每次遍历出一个连通图 , 如果这个图只有1个割点 ,
那么标记一个 , 如果超过1个黑点, 就不要标记 , 因为 , 每次只删除 一个割点 , 所有当这个连通图连接了两个割点时 ,
就一点可以到达其他黑点 。 而如果整个图都没有黑点 , 则不需要遍历 , 可知只有2个黑点 。

2、先求出这个图中的所有bcc , 就判断每个bcc , 如果这个bcc只有1个割点 , 那就要标记1个黑点 ,
其他的则不需要进行标记 。

代码 :

1、

#include

#include

#include

#include

using namespace std ;

const int MAXN = 200100;

vectorgrap[MAXN] ;

int pre[MAXN] , iscut[MAXN];

int n = 0, m = 0, dfs_clock = 0;

int bz[MAXN] , d = 0 , f = 1 , bz2[MAXN];

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])

   
    {

   
   
    child +=
1;

   
   
    int lowv =
dfs(v , u);

   
   
    if(lowv <
lowu)  lowu = lowv;

   
   
    if(lowv
>= pre[u])

   
   
    {

   
   
   
    iscut[u] =
1;

   
   
   
    d +=
1;

   
   
   
    bz[u] =
1;

   
   
    }

   
    }

   
    else
if(pre[v] < pre[u] && v != fu)

   
    {

   
   
    if(pre[v]
< lowu)

   
   
   
    lowu =
pre[v];

   
    }

    }

    if( fu <
0 && child == 1)

    {

   
    if(iscut[u]
== 1)

   
    {

   
   
    d -=
1;

   
   
    iscut[u] = 0
;

   
   
    bz[u] =
0;

   
    }

    }

    return
lowu;

}

void dfs_find(int u)

{

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

    {

   
    int v =
grap[u][i];

   
    if(bz2[v]==0
&& iscut[v])

   
    {

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