BZOJ2199: [Usaco2011 Jan]奶牛议会(2-SAT)

2024-03-19 04:10

本文主要是介绍BZOJ2199: [Usaco2011 Jan]奶牛议会(2-SAT),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 559  Solved: 360
[Submit][Status][Discuss]

Description

由于对Farmer John的领导感到极其不悦,奶牛们退出了农场,组建了奶牛议会。议会以“每头牛 都可以获得自己想要的”为原则,建立了下面的投票系统: M只到场的奶牛 (1 <= M <= 4000) 会给N个议案投票(1 <= N <= 1,000) 。每只 奶牛会对恰好两个议案 B_i and C_i (1 <= B_i <= N; 1 <= C_i <= N)投 出“是”或“否”(输入文件中的'Y'和'N')。他们的投票结果分别为VB_i (VB_i in {'Y', 'N'}) and VC_i (VC_i in {'Y', 'N'})。 最后,议案会以如下的方式决定:每只奶牛投出的两票中至少有一票和最终结果相符合。 例如Bessie给议案1投了赞成'Y',给议案2投了反对'N',那么在任何合法的议案通过 方案中,必须满足议案1必须是'Y'或者议案2必须是'N'(或者同时满足)。 给出每只奶牛的投票,你的工作是确定哪些议案可以通过,哪些不能。如果不存在这样一个方案, 输出"IMPOSSIBLE"。如果至少有一个解,输出: Y 如果在每个解中,这个议案都必须通过 N 如果在每个解中,这个议案都必须驳回 ? 如果有的解这个议案可以通过,有的解中这个议案会被驳回 考虑如下的投票集合: - - - - - 议案 - - - - - 1 2 3 奶牛 1 YES NO 奶牛 2 NO NO 奶牛 3 YES YES 奶牛 4 YES YES 下面是两个可能的解: * 议案 1 通过(满足奶牛1,3,4) * 议案 2 驳回(满足奶牛2) * 议案 3 可以通过也可以驳回(这就是有两个解的原因) 事实上,上面的问题也只有两个解。所以,输出的答案如下: YN?

Input

* 第1行:两个空格隔开的整数:N和M * 第2到M+1行:第i+1行描述第i只奶牛的投票方案:B_i, VB_i, C_i, VC_i

Output

* 第1行:一个含有N个字符的串,第i个字符要么是'Y'(第i个议案必须通过),或者是'N' (第i个议案必须驳回),或者是'?'。 如果无解,输出"IMPOSSIBLE"。

Sample Input


3 4
1 Y 2 N
1 N 2 N
1 Y 3 Y
1 Y 2 Y


Sample Output

YN?

HINT

Source

Gold

 
2-SAT应该能一眼看出来。
不过这个方案有点鬼畜啊 。。
题目中要求的是“所有方案”
然后我自己YY了一种在方向图上的暴力方法
写了160+把自己的思路叉掉了
看了hzwer的博客发现连tarjan都不用,
直接暴力枚举就行QWQ。。
时间复杂度:$O(n*m)$
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
#include<queue>
#include<iostream>
#define Pair pair<int,int>
#define F first
#define S second
using namespace std;
const int MAXN=1e6+10;
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
char buf[1<<20],*p1=buf,*p2=buf;
inline int read()
{    char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}
struct node
{int u,v,w,nxt;
}edge[MAXN];
int head[MAXN],num=1;
int N,M;
int vis[MAXN],ans[MAXN];
inline void AddEdge(int x,int y)
{edge[num].u=x;edge[num].v=y;edge[num].nxt=head[x];head[x]=num++;
}
int dfs(int x)
{vis[x]=1;for(int i=head[x];i!=-1;i=edge[i].nxt)if(!vis[edge[i].v])dfs(edge[i].v);
}
int check(int x)
{memset(vis,0,sizeof(vis));dfs(x);if(x<=N&&vis[x]&&vis[x+N])  return 0;if(x>N&&vis[x]&&vis[x-N]) return 0;return 1;
}
int main()
{#ifdef WIN32freopen("a.in","r",stdin);#else#endifmemset(head,-1,sizeof(head));N=read(),M=read();for(int i=1;i<=M;i++){int a,b;char x,y;a=read();while(x!='Y'&&x!='N') x=getchar();b=read();while(y!='Y'&&y!='N') y=getchar();if(x=='Y') if(y=='Y') AddEdge(a+N,b),AddEdge(b+N,a);else AddEdge(a+N,b+N),AddEdge(b,a);else //x==Nif(y=='Y') AddEdge(a,b),AddEdge(b+N,a+N);else AddEdge(a,b+N),AddEdge(b,a+N);x='0';y='0';}    for(int i=1;i<=N;i++){int ans1=check(i);int ans2=check(i+N);if(ans1&&ans2) ans[i]=1;//else if(ans1) ans[i]=2;//Yelse if(ans2) ans[i]=3;//Nelse {printf("IMPOSSIBLE\n");return 0;}}for(int i=1;i<=N;i++){if(ans[i]==1) putchar('?');else if(ans[i]==2) putchar('Y');else if(ans[i]==3) putchar('N');}return 0;
}

 

这篇关于BZOJ2199: [Usaco2011 Jan]奶牛议会(2-SAT)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

新SAT官方范文得分的分段分析

· 本次官方给出了两道写作新样题,样题的材料文章分别是节选自Paul Bogard于2012.12.21发表在《洛杉矶时报》的“Let There Be Dark.”及Dana Gioia于2005.04.10发表在《纽约时报》的“Why Literature Matters” 。   · 张卉老师结合之前的新SAT改革的说明,认为写作部分的基本出题思路没有大的调整,样题的材料文章都是节选自

SAT改革:SAT官方最新样题解读与备考建议

College Board于2015年1月9日释放新SAT考试最新样题,小编第一时间为各位考生及家长进行新SAT考试的样题解析及备考规划建议,此次小编给出了SAT语法样题一、样题二,阅读第一、二篇,数学,写作样题与范文的详细解读,希望各位考生在2015冲刺高分成绩! 新SAT科目官方样题答案解析新SAT语法新SAT写作与语法能力真题及答案样题1解析 | 样题2解析 | 新SAT语法备考建议新

SAT阅读考试的典型问题及应对策略

SAT阅读部分的测试时间为70分钟,共65道选择题,每道选择题有五项选择,其中只有一项选择为正确答案。结合所阅读的文章,每道选择题以提出问题的形式出现,通常被问到的问题类型为:本篇文章的主要观点及中心主题;在本篇文章中,作者对所论述问题的态度及基本观点;判断所阅读文章的体裁形式,例如:议论、寓言、科技、历史、讽刺、悲剧、喜剧、浪漫、科幻、恐怖、写实及诗歌;作者在文章中所用的修辞手法的目的,在这

如何克服SAT考试阅读难关?

对中国考生而言,SAT阅读部分的考题为最难。SAT阅读由两部分组成,即阅读判断及句子填空,全部为选择题型。SAT阅读的考试时间为70分钟,65道题,每答对一道题得12.3分,总共800分。国内考生若想在SAT阅读中取得理想的成绩,至少要具备两项基本能力,其一,要掌握一万左右的英语词汇量;其二,要有能力根据上下文的关系,准确识别不认识的英语词汇。SAT阅读部分题量大、时间紧,考生要在不超过一分钟

四步走循序渐进克服SAT阅读关

五月份的SAT考试刚刚结束,阅读自然是各个部分中最有难度的,也是最令同学们望而生畏的。但相较于几个月前,同学们纷纷表示,在经过了系统而全面的训练和练习之后,还是可以打倒阅读这一SAT高分路上拦路虎的。 事实上,只要过了四个关卡,同学们就可彻底解决SAT阅读。   第一关:单词关   要读懂一篇文章,无疑最基本的一点是要认识这篇文章的字。如果入目皆是生词,一定会有一种“满纸荒唐言”的感觉――

考生备考分享:SAT阅读提分技巧

不少同学认为阅读是SAT考试中最难的部分,很多人抱怨时间太紧做不完题,也有很多人说做完题了但是正确率很低。在经历了第一次SAT后,我总结了一些的阅读经验,凭借运用这些经验,我的第二次SAT阅读成绩有了非常大的进步。现在将这些经验分享给大家。   1、在做阅读题时,首先应该把文章通读一遍,但这种通读并不是漫无目的的浏览,而是要筛选着读。   在这一遍里,要注意发掘、总结作者的核心思想是什么,

如何跨越SAT阅读词汇的障碍

SAT 阅读词汇对考生的要求一般是在数量上要越多越好,但是对于一些比较常见的词汇,大家还是需要掌握一个记忆原则,就是要精确掌握词汇的含义,这样才能在SAT阅读题目中做到有备无患,不被词汇拦住解题的道路。   由于很多同学把精力和时间都放在快速增加词汇量上,很多考生在记忆SAT阅读词汇的时候都会犯浅尝辄止,不求甚解的毛病,认为只要知道个大概意思,在阅读文章中根据上下文就可以猜到含义了,以至于对

二战SAT阅读成功经验分享:掌握时间规律

不少同学认为阅读是SAT中最难的部分,很多人抱怨时间太紧做不完题,也有很多人说做完题了但是正确率很低。在经历了第一次SAT后,我总结了一些的阅读经验,凭借运用这些经验,我的第二次SAT阅读成绩有了非常大的进步。现在将这些经验分享给大家。   1、在做阅读题时,首先应该把文章通读一遍,但这种通读并不是漫无目的的浏览,而是要筛选着读。   在这一遍里,要注意发掘、总结作者的核心思想是什么,文章

考生经验谈:如何做好SAT阅读的时间掌控

许多同学认为SAT阅读是SAT考试中最难的一个部分,大部分同学都表示问题出在时间上,很多人觉得时间太紧没法做完题,有些人表示即使做完题了正确率也很低。那么该如何合理安排SAT阅读的时间呢,根据我两次参加SAT考试的经验,我总结出了下面三点SAT阅读时间的规律,现与大家分享。   1、在做阅读题时,首先应该把文章通读一遍,但这种通读并不是漫无目的的浏览,而是要筛选着读。   在这一遍里,要注

SAT阅读高分技巧:带着问题通读全文

在这一遍里,要注意发掘、总结作者的核心思想是什么,文章的结构是怎样的,每个部分是什么意思。该详读的地方:首段,末段,每段开头和结尾,转折句,结论句。在这些地方可以用笔画出来或者在旁边做标记,这样利于答题。可以略读的地方:例子、形容词、副词等。不要纠结于一些陌生的单词而止步不前,因为这些单词不一定是重点内容,也可能在下文中可以推测出该词的意思。再次,对文章开始三分之一左右的内容要读得仔细一些,因