题意

有A,B,C三个任务要分配给n个宇航员,其中每个宇航员恰好要分配一个任务。设所有n个宇航员的平均年龄为x,只有年龄大于或等于x的宇航员才能分配任务A;只有年龄严格小于x的宇航员才能分配任务B,而任务C没有限制。有m对宇航员相互讨厌,因此不能分配到同一任务。编程找出一个满足上述所有要求的任务分配方案。

分析

这个题应该算是比较裸的2-sat了。

对于每个宇航员来说,他的年龄要么大于x要么小于x,所有他只能从A或者B里面选择一个。因此每个宇航员可以选择的任务只有两个A或者B 和C,对应2-sat问题中每个布尔型变量的真和假。有m对宇航员相互讨厌对应2-sat问题中的m条限制。如果两个宇航员年龄都大于x或者都小于x,我们称这两个宇航员为同一种类型。那么xi和xj必须不相同。则用两个条件进行限制。 “xi为真或者xj为真”,“xi为假或者xj为假”。如果两个宇航员为不同类型,那么只需要一个限制“xi为真或者xj为真”。

下面是代码

 #include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector> using namespace std;
const int maxn=+;
struct TwoSAT{
int n;
vector<int>G[*maxn];
bool mark[maxn*];
int S[maxn*],c;
bool dfs(int x){
if(mark[x^])return false;
if(mark[x])return true;
mark[x]=true;
S[c++]=x;
for(int i=;i<G[x].size();i++){
if(!dfs(G[x][i]))return false;
}
return true;
}
void init(int n){
this->n=n;
for(int i=;i<n*;i++)G[i].clear();
memset(mark,,sizeof(mark));
}
void add_clause(int x,int xval,int y,int yval){
x=x*+xval;
y=y*+yval;
G[x^].push_back(y);
G[y^].push_back(x);
} bool solve(){
for(int i=;i<n*;i+=){
if(!mark[i]&&!mark[i+]){
c=;
if(!dfs(i)){
while(c>)mark[S[--c]]=false;
if(!dfs(i+))return false;
}
}
}
return true;
}
}solver;
int age[maxn],n,m,X;
int kase;
int main(){
kase=;
while(scanf("%d%d",&n,&m)!=EOF&&(n||m)){
if(kase)printf("\n");
++kase;
X=;
solver.init(n);
for(int i=;i<n;i++){
scanf("%d",&age[i]);
X+=age[i];
}
int x,y;
for(int i=;i<=m;i++){
scanf("%d%d",&x,&y);
x--,y--;
if(age[x]*n>=X&&age[y]*n>=X){
solver.add_clause(x,,y,);
solver.add_clause(x,,y,);
}
if(age[x]*n<X&&age[y]*n<X){
solver.add_clause(x,,y,);
solver.add_clause(x,,y,);
}
else{
solver.add_clause(x,,y,);
}
}
if(!solver.solve()){
printf("No solution.");
continue;
}
for(int i=;i<n;i++){
if(solver.mark[*i+]){
if(age[i]*n>=X){
printf("A\n");
}else{
printf("B\n");
}
}else{
printf("C\n");
}
}
}
return ;
}

【LA3713 训练指南】宇航员分组 【2-sat】的更多相关文章

  1. 【UVA11107 训练指南】Life Forms【后缀数组】

    题意 输入n(n<=100)个字符串,每个字符串长度<=1000,你的任务是找出一个最长的字符串使得超过一半的字符串都包含这个字符串. 分析 训练指南上后缀数组的一道例题,据说很经典(估计 ...

  2. 训练指南 UVALive - 3713 (2-SAT)

    layout: post title: 训练指南 UVALive - 3713 (2-SAT) author: "luowentaoaa" catalog: true mathja ...

  3. poj 1961 Period(KMP训练指南例题)

    Period Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 11356   Accepted: 5279 Descripti ...

  4. 算法竞赛入门经典训练指南——UVA 11300 preading the Wealth

    A Communist regime is trying to redistribute wealth in a village. They have have decided to sit ever ...

  5. [置顶] 刘汝佳《训练指南》动态规划::Beginner (25题)解题报告汇总

    本文出自   http://blog.csdn.net/shuangde800 刘汝佳<算法竞赛入门经典-训练指南>的动态规划部分的习题Beginner  打开 这个专题一共有25题,刷完 ...

  6. 【LA3523 训练指南】圆桌骑士 【双连通分量】

    题意 有n个骑士经常举行圆桌会议,商讨大事.每次圆桌会议至少应有3个骑士参加,且相互憎恨的骑士不能坐在圆桌旁的相邻位置.如果发生意见分歧,则需要举手表决,因此参加会议的骑士数目必须是奇数,以防赞同和反 ...

  7. 训练指南 UVALive - 3126(DAG最小路径覆盖)

    layout: post title: 训练指南 UVALive - 3126(DAG最小路径覆盖) author: "luowentaoaa" catalog: true mat ...

  8. 训练指南 UVALive - 3415(最大点独立集)

    layout: post title: 训练指南 UVALive - 3415(最大点独立集) author: "luowentaoaa" catalog: true mathja ...

  9. 训练指南 UVA - 11419(二分图最小覆盖数)

    layout: post title: 训练指南 UVA - 11419(二分图最小覆盖数) author: "luowentaoaa" catalog: true mathjax ...

随机推荐

  1. 使用service&scope 进行注入

    @service 声明该类为一个bean,bean的名称为类名首字母小写(customerService) @Scope("prototype")则声明为一个原子类型,既每个get ...

  2. ballerina 学习十三 函数&&documentation

    ballerina 函数和其他语言一样的,可以实现重用 简单例子 代码 import ballerina/io; documentation { `User` is a user defined ob ...

  3. linux 磁盘挂载操作

    1. fdisk  -l      查看磁盘   2. fisk  /dev/vdb   进行分区        依次输入  n  p  1   两次回车  wq   3. fdisk -l  查看分 ...

  4. Extjs tree1

    1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://w ...

  5. vim 编辑技巧

    vi是linux下最常用的编辑器,vim是vi的加强版,本篇将介绍vim的一些快捷键和使用技巧,借鉴网上其他文章表示

  6. k8s1.4.3安装实践记录(3)下载基础镜像

    下载基础镜像,因为Google被墙,所以我们用时速云中的镜像来tag docker pull index.tenxcloud.com/google_containers/pause-amd64:3.0 ...

  7. java代码--实现随机输出10个随机数,并显示最大值,最小值

    总结;对于length()属性,还不是很熟悉.不会用它. package com.s.x; //随机产生10个随机数,并且显示出最大值,最小值 public class Love { public s ...

  8. mongodb一些语法

    一.DB shell数据操作 shell命令操作语法和JavaScript很类似,其实控制台底层的查询语句都是用JavaScript脚本完成操作的. Ø 数据库   1.Help查看命令提示 help ...

  9. click 模块使用方法说明

    !/usr/bin/env python -- coding: utf-8 -- import click @click.command() @click.option('--count', defa ...

  10. orzdba_monitor.sh脚本使用

    1.orzdba_monitor.sh脚本使用 ./orzdba_monitor.sh 主要是用nohup同时在后台调用orzdba,启动下面三个命令 [root@node02 scripts]# p ...