您的位置:首页 > 其它

LA 3713 Astronauts

2013-12-14 20:02 495 查看
这同样是一个2—sat 加建图的问题。

建图是有一个关键点:只有某种情况是“唯一”、“确定”是才能对这种情况进行连边 。切记 , 这点在所有建图中都很关键 ,
往往出错就是在这出的错 。 这题就是一个很好的例子 。

首先可以确定 , 每个宇航员只有两种选择 , 假设宇航员 a 、 b , 的年龄一个大于平均 , 一个小于平均
,那么连边是就只要连接当a选 c任务时 , b 就不能选 c 任务 , 反过来也是 , 而没必要连接当a 不选c任务时的情况 ,
因为此时的情况是不确定的 , 也就是没有唯一性 。

代码:

#include

#include

#include

#include

#include

#include

#include

using namespace std;

const int MAXN = 100010 ;

vectorgrap[MAXN*2] ;  // 存储建的图

bool mark[MAXN*2] ;  // 标记已经确定任务的宇航员

int age[MAXN] , s[MAXN*2] , n = 0, m = 0, c ;

void init()

{

    for(int i =
0 ; i < n*2 ; i++)

   
   
grap[i].clear();

    memset(mark
, 0 , sizeof(mark));

   

    c = 0;

}

bool dfs(int x)

{

   
if(mark[x^1])  return false;  //
如果一个宇航员连个任务都被标记了 , 那么这是不可以 , 也就是false

   
if(mark[x])  return true;

    mark[x] =
true ;

    s[c++] =
x;

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

   
   
if(!dfs(grap[x][i]))  return false;

    return true
;

}

bool solve()

{

    for(int i =
0 ; i < 2*n; i += 2)

    {

   
    if(!mark[i]
&& !mark[i+1])

   
    {

   
   
    c = 0;

   
   
   
if(!dfs(i))

   
   
    {

   
   
   
    while(c >
0)  mark[s[--c]] = false ;

   
   
   
   
if(!dfs(i+1))  return false;

   
   
    }

   
    }

    }

    return true
;

}

int main()

{

   
while(scanf("%d %d" , &n , &m) != EOF)

    {

   
   
init();

   
   
if(!n&&!m)  break;

   
    int i , sum
= 0;

   
    for(i = 0 ;
i < n; i++)

   
    {

   
   
    scanf("%d" ,
&age[i]);

   
   
    sum +=
age[i];

   
    }

   
    double p_age
= (double)sum/n ;

   
    int x ,
y;

   
    for(i = 0 ;
i < m; i++)

   
    {

   
   
    scanf("%d
%d" , &x , &y);

   
   
    x -=
1;

   
   
    y -=
1;

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