lightoj 1407 2-sat
这题的英语either...or....很蛋疼;
m中,1:x与y至少一个出席;2:x出席,y随便,x不出席,y也不出席----这有个坑,可以推出y出席x也一定出席(这个关系必须要连上);3x与y至少一个不出席 4,x与y有且只有一个出席。
对于k中的数据:我琢磨很久,关系在图上是建不了的,type为1时三个人至少有一个人要出席,则三个都不出席的情况是不允许的,dfs的时候判断一下就是了,同理type为2的情况。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxn = ;
const int maxe = ;
const int INF = 0x3f3f3f; int n,m,k;
struct node{
int type,x,y,z;
}a[]; struct TwoSat{
int n;
int mark[maxn*];
int s[maxn*],cnt;
vector<int> G[maxn*]; void init(int n){
this->n = n;
for(int i=;i<=*n+;i++) G[i].clear();
memset(mark,,sizeof(mark));
}
void add_clause1or3(int u,int uval,int v,int vval){
u = u* + uval; //u与v不共存;
v = v* + vval;
G[u].push_back(v^);
G[v].push_back(u^);
}
void add_clause2(int u,int uval,int v,int vval){
u = u* + uval;
v = v* + vval;
G[u].push_back(v);
G[v^].push_back(u^);
}
void add_clause4(int u,int uval,int v,int vval){
u = u* + uval;
v = v* + vval;
G[u^].push_back(v);
G[u].push_back(v^);
G[v^].push_back(u);
G[v].push_back(u^);
} bool JudgeWrong(){
for(int i=;i<k;i++){
if(a[i].type == ){
int x = *a[i].x+,y = *a[i].y+,z = *a[i].z+;
if(mark[x] && mark[y] && mark[z]) return true;
}
if(a[i].type == ){
int x = *a[i].x,y = *a[i].y,z = *a[i].z;
if(mark[x] && mark[y] && mark[z]) return true;
}
}
return false;
} bool dfs(int u){
if(mark[u^]) return false;
if(mark[u]) return true;
mark[u] = true;
s[cnt++] = u;
if(JudgeWrong()) return false; for(int i=;i<G[u].size();i++)
if(!dfs(G[u][i])) return false;
return true;
} bool solve(){
for(int i=;i<=*n;i+=)
if(!mark[i] && !mark[i+]){
cnt = ;
if(!dfs(i)){
while(cnt > ) mark[s[--cnt]] = false; //要回溯;
if(!dfs(i+)) return false;
}
} return true;
} void print(){
int ans[maxn],pv = ;
for(int i=;i<=*n;i+=)
if(mark[i]) ans[pv++] = i/; printf("%d",pv);
for(int i=;i<pv;i++) printf(" %d",ans[i]);
printf(".\n");
} }solver; int main()
{
//freopen("E:\\acm\\input.txt","r",stdin);
int T;
cin>>T;
for(int t=;t<=T;t++){
scanf("%d %d %d",&n,&m,&k);
solver.init(n);
for(int i=;i<=m;i++){
int type,x,y;
scanf("%d %d %d",&type,&x,&y);
if(type == ) solver.add_clause1or3(x,,y,);
else if(type == ) solver.add_clause2(x,,y,);
else if(type == ) solver.add_clause1or3(x,,y,);
else solver.add_clause4(x,,y,);
}
for(int i=;i<k;i++)
scanf("%d %d %d %d",&a[i].type,&a[i].x,&a[i].y,&a[i].z);
if(solver.solve()){
printf("Case %d: Possible ",t);
solver.print();
}
else printf("Case %d: Impossible.\n",t);
}
}
lightoj 1407 2-sat的更多相关文章
- Beauty of Array(模拟)
M - M Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu Submit Status P ...
- 区间DP LightOJ 1422 Halloween Costumes
http://lightoj.com/volume_showproblem.php?problem=1422 做的第一道区间DP的题目,试水. 参考解题报告: http://www.cnblogs.c ...
- 多边形碰撞 -- SAT方法
检测凸多边形碰撞的一种简单的方法是SAT(Separating Axis Theorem),即分离轴定理. 原理:将多边形投影到一条向量上,看这两个多边形的投影是否重叠.如果不重叠,则认为这两个多边形 ...
- LightOj 1298 - One Theorem, One Year(DP + 欧拉)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1298 题意:给你两个数 n, p,表示一个数是由前 k 个素数组成的,共有 n 个素数 ...
- 1214 - Large Division -- LightOj(大数取余)
http://lightoj.com/volume_showproblem.php?problem=1214 这就是一道简单的大数取余. 还想还用到了同余定理: 所谓的同余,顾名思义,就是许多的数被一 ...
- LightOJ Beginners Problems 部分题解
相关代码请戳 https://coding.net/u/tiny656/p/LightOJ/git 1006 Hex-a-bonacci. 用数组模拟记录结果,注意取模 1008 Fibsieve's ...
- LightOJ 1341 唯一分解定理
Aladdin and the Flying Carpet Time Limit:3000MS Memory Limit:32768KB 64bit IO Format:%lld &a ...
- lightoj 1370 欧拉函数
A - Bi-shoe and Phi-shoe Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & % ...
- lightoj 1074 spfa判断负环
Extended Traffic Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu Sub ...
随机推荐
- java异常类的使用
1.异常的概念 什么是异常?程序出错分为两部分,编译时出粗和运行时出错.编译时出错是编译器在编译源码时发生的错误: 运行时出错是在编译通过,在运行时出现的错误.这种情况叫异常. 例如:数组越界,除数为 ...
- mac 下maven的安装
最近在学习mahout,这些安装相关软件的步骤先记下来,避免以后忘记. 1.首先在mac上查看本机的java版本,如果没有需要自己去安装: 我的电脑上安装的java是1.7.0_79 2.在http: ...
- 【POJ2887】【块状链表】Big String
Description You are given a string and supposed to do some string manipulations. Input The first lin ...
- c#的异或运算符
int a = 5; int b = 30; Console.WriteLine(a^b); Console.ReadKey(); 输出结果是27 这是因为 5的二进制是0000 010130的二进 ...
- Android中AppWidget的分析与应用:AppWidgetProvider .
from: http://blog.csdn.net/thl789/article/details/7887968 本文从开发AppWidgetProvider角度出发,看一个AppWidgetPrv ...
- [r]Ubuntu Linux系统下apt-get命令详解
Ubuntu Linux系统下apt-get命令详解(via|via) 常用的APT命令参数: apt-cache search package 搜索包 apt-cache show package ...
- javascript定义类的方法总结
1.构造函数法 类是对象的模板,定义了对象共有的方法属性数据 等,在javascript中一个函数就是一个对象,也可以看做一个类的构造方法. 所以我们可以像以下方式定义类: //1.经典的构造方法 Q ...
- SQL联合索引 与 单一列的索引
SQL联合索引 与 单一列的索引 标签: sqlwebobjectstatistics优化磁盘 2012-06-12 13:46 27992人阅读 评论(1) 收藏 举报 分类: 数据库(94) ...
- jQuery Ajax 分页插件
很多社交网站都使用无限滚动的翻页技术来提高用户体验,当你页面滑到列表底部时候无需点击就自动加载更多的内容 很多社交网站都使用无限滚动的翻页技术来提高用户体验,当你页面滑到列表底部时候无需点击就自动加载 ...
- BZOJ 1507 Editor
Description Input 输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作.其中: 为了使输入文件便于阅读,Insert操作的字符串中可能会插入一些回车符,请忽略掉它 ...