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;
建图是有一个关键点:只有某种情况是“唯一”、“确定”是才能对这种情况进行连边 。切记 , 这点在所有建图中都很关键 ,
往往出错就是在这出的错 。 这题就是一个很好的例子 。
首先可以确定 , 每个宇航员只有两种选择 , 假设宇航员 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;
相关文章推荐
- LA 3211 Now or later
- uva 11324
- LA 5135 Mining Your Own Business
- http://kb.cnblogs.com/page/130970/ -http协议
- poj 2942 LA3523 点-双…
- uva 10047
- STL中优先队列的用法
- 并查集及其路径的压缩
- 求欧拉回路的路径 dfs的一种新运用
- poj 2676
- poj 2531
- poj 2251
- poj 2488
- 网络流 SAP优化算法 (…
- 网络流之Dinic算法
- 基于增广路的网络流算法
- poj 1789 最小生成树
- poj 1469
- poj 3041二分匹配
- scanf和cin的区别 (效率的差距)