LA 3713 Astronauts
来源:互联网 发布:linux解析文件 编辑:程序博客网 时间:2024/05/20 05:11
这同样是一个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;
建图是有一个关键点:只有某种情况是“唯一”、“确定”是才能对这种情况进行连边 。切记 , 这点在所有建图中都很关键 ,往往出错就是在这出的错 。 这题就是一个很好的例子 。
首先可以确定 , 每个宇航员只有两种选择 , 假设宇航员 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()
{
}
bool dfs(int x)
{
}
bool solve()
{
}
int main()
{