uva 1086 - The Ministers' Major Mess(2 SAT)

2024-06-05 00:58
文章标签 major uva sat 1086 mess ministers

本文主要是介绍uva 1086 - The Ministers' Major Mess(2 SAT),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接:uva 1086 - The Ministers' Major Mess


枚举每个点,判断是否y,n都存在解,如果都存在即为?, 最后做一遍2SAT即可。


#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>using namespace std;
const int maxn = 105;struct TwoSAT {int n, S[maxn * 2], C;bool mark[maxn * 2], must[maxn * 2];vector<int> G[maxn * 2];void init (int n) {this->n = n;memset(must, 0, sizeof(must));for (int i = 0; i < n*2; i++) G[i].clear();}void clear() { memcpy(mark, must, sizeof(must)); }void addClause(int x, int xflag, int y, int yflag) {x = x * 2 + xflag;y = y * 2 + yflag;G[x^1].push_back(y);G[y^1].push_back(x);}void draw(int u) {must[u] = true;for (int i = 0; i < G[u].size(); i++)if (!must[G[u][i]]) draw(G[u][i]);}bool dfs (int u) {if (mark[u^1]) return false;if (mark[u]) return true;mark[u] = true;S[C++] = u;for (int i = 0; i < G[u].size(); i++)if (!dfs(G[u][i])) return false;return true;}bool solve () {for (int i = 0; i < 2*n; i += 2) {if (mark[i] && mark[i+1]) return false;if (!mark[i] && !mark[i+1]) {C = 0;if (!dfs(i)) {while (C) mark[S[--C]] = false;if (!dfs(i+1)) return false;}}}return true;}
}solver;int N, M, T[maxn];void init () {int k, x[10], y[10];char s[10];solver.init(N);memset(T, 0, sizeof(T));while (M--) {scanf("%d", &k);for (int i = 0; i < k; i++) {scanf("%d%s", &x[i], s);x[i]--; y[i] = s[0] == 'y' ? 0 : 1;}if (k >= 3) {for (int i = 0; i < k; i++)for (int j = i + 1; j < k; j++)solver.addClause(x[i], y[i], x[j], y[j]);} else {for (int i = 0; i < k; i++)solver.must[x[i]*2+y[i]] = true;}}
}int main () {int cas = 1;while (scanf("%d%d", &N, &M) == 2 && N + M) {init();for (int i = 0; i < 2*N; i++)if (solver.must[i]) solver.draw(i);for (int i = 0; i < 2*N; i += 2) {if (solver.must[i] || solver.must[i+1]) continue;solver.clear();solver.mark[i] = true;bool flag1 = solver.solve();solver.clear();solver.mark[i+1] = true;bool flag2 = solver.solve();if (flag1 && flag2) T[i/2] = 1;}solver.clear();printf("Case %d: ", cas++);if (!solver.solve()) printf("impossible\n");else {for (int i = 0; i < N; i++) {if (T[i]) printf("?");else if (solver.mark[i*2]) printf("y");else printf("n");}printf("\n");}}return 0;
}


这篇关于uva 1086 - The Ministers' Major Mess(2 SAT)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1031628

相关文章

由于jdk版本问题引起的Unsupported major.minor version 52.0

tomcat启动报错 错误日志信息: 三月 01, 2019 9:47:02 下午 org.apache.catalina.core.ApplicationContext log INFO: Initializing Spring root WebApplicationContext 三月 01, 2019 9:47:08 下午 org.apache.catalina.core.Standard

UVA - 12206 Stammering Aliens (hash)

这题其实很容易想到2分长度,关键是2分后,怎么判断出现最多次的串是否》=m次了。这里需要用到hash来处理。 对于一个字符串   H[i] =H[i+1]*131+s[i]  ;其中 H[n]=0;那么对于一个长度为L的串 ,hanh[i,l]=H[i]-H[i+L]*x^L ; 这样记录每个字符串的hash值,然后再处理起来就比较简单了。 VIEW CODE #include<

Linux 内核权限提升漏洞CVE-2024-1086三种修复方法

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 一、漏洞概述 漏洞成因: Netfilter是Linux内核中的一个数据包处理模块,它可以提供数据包的过滤、转发、地址转换NAT功能。 2024年3月28日,监测到 Linux kernel权限

[Uva 11990] Dynamic Inversion (CDQ分治入门)

Uva - 11990 动态逆序对,求删除一个点之前序列中逆序对的个数 首先倒过来看这个问题,把点先全部删掉 然后从最后一个点开始倒着往数列中加点 求加完这个点逆序对的变化 CDQ分治做法 把删除时间看作 t,下标看作 x,值看作 y 然后对 x排序,对 t偏序,用树状数组维护 y 具体来说就是对于每个点 (t0,x0,y0) (t_0, x_0, y_0) 先统计

com/android/dx/command/dexer/Main : Unsupported major.minor version 52.0

如果你在开发过程中遇到了上述的Bug,基本上是JDK版本不一致造成的,指的是高版本的JDK编译的class不能放在低版本的JDK上运行。 如果是Version 52,就表示JDK8编译的class不能运行在JDK7上,所以需要在本地安装JDK8. 如果是Version 51,就表示JDK7编译的class不能运行在JDK6上,所以需要在本地安装JDK7.

UVA 11624 搜索

给出1000*1000矩阵,含起点‘J’,路‘.',墙‘#’,火‘F'; 火每秒蔓延一格,人每秒走一步 问人是否可以安全走出矩阵,不能被火碰到 先对所有火BFS一遍,记录每个点被烧到的时间 然后对人BFS一遍,若到每点前没被火烧即可走 #include "stdio.h"#include "string.h"#include "queue"using namespace

UVa 11361 Investigating Div-Sum Property

这道题居然提交了十次才过....期间小问题不断。思路的话基本是《训练指南》里面来的,不过有几个小问题需要注意一下。第一,当K在大于100的情况下,就直接输出0就可以了。因为a,b不超过2^31,可以估算出a,b最多十位十进制数,那么每位最大为9,所以各个数字之和是不可能超过100的,那么个数字之和为模K为0的条件是永远不可能到达的。       还有一点是,当剩余数字d=0时,当且

UVa 1362(LA 3516) Exploring Pyramids

依旧是《训练指南》上的一道例题。思路大致相同,即设有一个序列S(i),S(i+1),S(i+2)...S(j),d[i,j]为所求的解。当S(i)==S(k),i<k<=j 时,说明在k回到根,那么S(i+1)...S(k-1)构成一棵独立的子树(当然也可能并不是子树)。那么d[i,j]就要加上d[i+1,k-1]*d[k,j],不断递增k,每遇到一个k,d[i,j]+=d[i

UVa 11174 Stand in a Line

依旧是《训练指南》上的一道例题。书上讲的比较抽象,下面就把解法具体一下。因为涉及到父子关系,因此自然而然可以将n个节点构造成一棵树,最后将形成一个森林。接下来将使用递归的手法。设f(i)是以节点i为树根的子树,节点i有儿子c1,c2,c3....cj共j棵子树。s[i]为树根为i的子树包含的节点数。如果分别先给各个子树内部排序,那么毫无疑问, 共有f(c1)*f(c2)*f(c3).

UVa 11375 Matches

大年夜的写代码果然状态非常之差...感觉特别困,连个高精度都折腾了我好久。还是刘汝佳《训练指南》里的一道例题,解题思路其实也差不多,但是想对书里面的内容再讲讲。其中d[i]是代表i个火柴棒恰好能构成的正整数数目(不包含整数0),然后有点类似于动态规划的做法,通过已知的d[]求出剩下的d[]。        不过仔细想来貌似有点问题。例如已知d[j],那么d[j+num[0]]+=d[