SPOJ 9939 Eliminate the Conflict
SPOJ_9939
这个题目可以用2-SAT做。
首先既然是2-SAT的问题的话,我们就要去找核心变量,然而B的每局的选择却是3个,石头(1)、剪子(2)、布(3),难道3-SAT?开玩笑,目前至少我没见过3-SAT的题目。仔细想一下,其实选择也就两个,因为A的选择是定的,而我们必须让A赢,因此B的选择实际上只有两个。
找到核心变量之后就是构图了,由于构图要稍复杂一些,就不直接用字母代替了,还是用一个实例来说明一下吧。
我们不妨一共3局,A出的分别是1、2、3,那么我们可以得到B的选择如下。
B1 1 2 1
B2 2 3 3
!B 3 1 2
其中B1、B2为B的两个选择,!B为B所不能选的。
现在假设M为2,分别为1 2 1、2 3 0,也就是说B的选择在第1局和第2局时必须不同,在第2局和第3局地选择必须相同。
首先我们建1 2 1这个要求的边。假设第1局选1的话,那么第2局选什么都无所谓的,因此没有必然的关系,所以第1局的1就不用连边了。假设第1局选2的话,那么第2局就一定要选3,这样就需要连一条左边的2到右边的3的有向边。同理,右边的2到左边的1也需要连一条有向边。
然后建2 3 0这个要求的边。假设第2局选2的话,就会发现第3局是选什么都不行的,因此第2局必然不能选2,因此我们需要连一条左边的2到左边的3的有向边,意思是如果第2局选了2那么第2局必然选3,这样在最后求可行解的时候就必然不会把2选入内,也就确保了第2局不会选2。假设第2局选3的话,那么显然第3局也必然选3,这样连一条左边的3到右边的3的有向边。同理,还需要连一条右边的1到右边的3的有向边,和一条右边的3到左边的3的有向边。
其实所有的边都按上面说的原理去构造就可以了。建完图之后的任务就轻松了,只需要tarjan求强连通分量、缩点,然后判断一下就可以了。
#include<stdio.h>#include<string.h>#define MAXD 20010#define MAXM 80010int e, first[MAXD], next[MAXM], v[MAXM], st[MAXD], A[MAXD];int dfn[MAXD], low[MAXD], color[MAXD], s[MAXD], top, cnt, col, ins[MAXD];int N, M;void add(int a, int b){ v[e] = b; next[e] = first[a]; first[a] = e; e ++;}void init(){int i, j, a, b, k, x, y; scanf("%d%d", &N, &M); memset(first, -1, sizeof(first)); e = 0;for(i = 0; i < N; i ++) { scanf("%d", &A[i]);if(A[i] == 1) { st[2 * i] = 1; st[2 * i ^ 1] = 2; A[i] = 3; }else if(A[i] == 2) { st[2 * i] = 2; st[2 * i ^ 1] = 3; A[i] = 1; }else { st[2 * i] = 1; st[2 * i ^ 1] = 3; A[i] = 2; } }for(i = 0; i < M; i ++) { scanf("%d%d%d", &a, &b, &k); a --; b --; x = 2 * a; y = 2 * b;if(k) {if(st[x] != A[b]) {if(st[x] == st[y]) add(x, y ^ 1);else add(x, y); }if(st[x ^ 1] != A[b]) {if(st[x ^ 1] == st[y]) add(x ^ 1, y ^ 1);else add(x ^ 1, y); }if(st[y] != A[a]) {if(st[y] == st[x]) add(y, x ^ 1);else add(y, x); }if(st[y ^ 1] != A[a]) {if(st[y ^ 1] == st[x]) add(y ^ 1, x ^ 1);else add(y ^ 1, x); } }else {if(st[x] == A[b]) add(x, x ^ 1);else {if(st[x] == st[y]) add(x, y);else add(x, y ^ 1); }if(st[x ^ 1] == A[b]) add(x ^ 1, x);else {if(st[x ^ 1] == st[y]) add(x ^ 1, y);else add(x ^ 1, y ^ 1); }if(st[y] == A[a]) add(y, y ^ 1);else {if(st[y] == st[x]) add(y, x);else add(y, x ^ 1); }if(st[y ^ 1] == A[a]) add(y ^ 1, y);else {if(st[y ^ 1] == st[x]) add(y ^ 1, x);else add(y ^ 1, x ^ 1); } } }}void tarjan(int u){int i; dfn[u] = low[u] = ++ cnt; s[top ++] = u; ins[u] = 1;for(i = first[u]; i != -1; i = next[i]) {if(!dfn[v[i]]) { tarjan(v[i]);if(low[v[i]] < low[u]) low[u] = low[v[i]]; }else if(ins[v[i]] && dfn[v[i]] < low[u]) low[u] = dfn[v[i]]; }if(low[u] == dfn[u]) {for(s[top] = -1; s[top] != u;) { top --; ins[s[top]] = 0; color[s[top]] = col; } col ++; }}int judge(){int i;for(i = 0; i < N; i ++)if(color[2 * i] == color[2 * i ^ 1])return 0;return 1;}void solve(){int i, j, k; col = cnt = top = 0; memset(dfn, 0, sizeof(dfn)); memset(ins, 0, sizeof(ins));for(i = 0; i < 2 * N; i ++)if(!dfn[i]) tarjan(i);if(judge()) printf("yes\n");else printf("no\n");}int main(){int t, tt; scanf("%d", &t);for(tt = 0; tt < t; tt ++) { init(); printf("Case #%d: ", tt + 1); solve(); }return 0;}
SPOJ 9939 Eliminate the Conflict相关推荐
- LSTM:《Long Short-Term Memory》的翻译并解读
LSTM:<Long Short-Term Memory>的翻译并解读 目录 Long Short-Term Memory Abstract 1 INTRODUCTION 2 PREVIO ...
- 割平面法只能求解纯整数规划吗_离散规划 解法
有限离散规划 可列离散规划 枚举法 Hahaha 图搜索枚举 2color 树搜索枚举 深度优先 广度优先 最大最小 蒙特卡洛 分支定界 剪枝 (混合)整数线性规划 MILP 三维整数规划 MILP ...
- 社区发现(二)--GN
转自:https://blog.csdn.net/aspirinvagrant/article/details/45599071 GN算法 本算法的具体内容请参考Finding and evaluat ...
- 【温故而知新】JavaWEB回顾(八)
1.说下原生 jdbc 操作数据库流程? 第一步: Class.forName()加载数据库连接驱动: 第二步: DriverManager.getConnection()获取数据连接对象; 第三步: ...
- Probabilistic Embeddings with Laplacian Graph Priors
具有拉普拉斯图先验的概率嵌入 Väinö Yrjänäinen 1 Måns Magnusson 11 Department of Statistics, Uppsala University, Up ...
- mb63.nte.ios.html,2009 Diagnosis, assessment, and treatment of non-pulmonary arterial hypertension
The 4th World Symposium on Pulmonary Hypertension was the ?rst international meeting to focus not on ...
- Day10. Work organization and mental health problems in PhD students
Title: Work organization and mental health problems in PhD students 工作组织与博士生心理健康问题 Keywords: Mental ...
- camon详细解决过程
原 基于Python的Cameo实现详解 2018年09月17日 15:51:00 weixin_41700557 阅读数:235 以下内容为学习<OpenCV 3计算机视觉Python与原实现 ...
- 关于非标准数学的感想
关于非标准数学的感想 一般认为,希尔伯特计划中的数学只有一种,包括非欧几何在内. 如今,出现了"非标准"数学,真是有点儿匪夷所思也.什么是非标准数学?它是什么东西?从何而来? 希尔 ...
最新文章
- 积跬步以至千里_积跬步以至千里,聚小利终成大户
- MySQL系统自带的数据库information schema
- LSI/LSA算法原理与实践Demo
- java连加密的mysql_Java 实现加密数据库连接
- 谷歌recaptcha验证码java解决方案
- POJ3579 Median【二分法+中位数】
- Java对象头与monitor
- 计算机网络(谢希仁第七版)期末重点
- php获取手机本地,PHP通过API获取手机号码归属地
- 戴尔微型计算机3048,戴尔5460一体机拆解,戴尔3048一体机
- 社团招新如何吸引新人,制作一张好的海报最关键
- python证明冰雹猜想_如果冰雹猜想被证明了。那数学会有很大突破吗?
- ArabellaCPC 2019 B. Road to Arabella
- 语音特征提取 matlab,基于matlab的语音信号特征提取方法研究
- 【Ubuntu16.04】ROS · Kinetic安装 · 图文教程与问题详解
- Redis详细教程-学习笔记
- 基于Python高校图书馆图书管理系统的设计与实现(PyCharm,MySQL)
- AbMole科研-THZ1通过抑制自噬增强Sirolimus诱导的细胞毒性
- Linux 有/无设备树下 platform_driver 驱动框架
- 如何连接ftp服务器