链接:

BZOJ-2199


题意:

给出 \(n(1\leq n\leq 1000)\) 个点,\(m(1\leq m\leq 4000)\) 个形如:“点 \(a\) 取 \(ca\) 或 点 \(b\) 取 \(cb\),其中 \(ca,cb\in\{'Y','N'\}\)” 的限制。如果没有一组方案满足所有限制,输出"IMPOSSIBLE";否则,可能有多组满足限制的解。对于一个点,如果在所有方案中都取 \('Y'\) 则该点最终答案为 \('Y'\),如果在所有方案中都取 \('N'\) 则该点最终答案为 \('N'\),如果都能取到,则该点最终答案为 \('?'\) ,输出最终 \(n\) 个点的答案。


分析:

我们知道,如果只需要一组答案,那么这就是 2-sat 的模板,但是该题似乎需要求出所有方案?

于是我们回顾使用 tarjan 算法求强连通分量解决 2-set 问题中最后取值的部分。

我们知道一个点的 true 和 false 我们会选择拓扑序较大的,这是因为拓扑序较小的可能会连向拓扑序较大的,而此时我们只能选择拓扑序较大的,不然会出现错误。我们发现这就是某个点必须选择某种取值的情况,即上文"在所有方案中都取XXX",而相对应的,如果无法从拓扑序较小的连向较大的,就说明这两种取值都能取,也就是上文“如果都能取到”的情况了。所以我们的算法思路也就比较清晰了。


算法:

在正常 2-sat 建图,tarjan 求强连通分量后,如果无解,输出"IMPOSSIBLE",否则对强连通分量建图,使用 bfs 判断每个点的两种取值的连通性即可。此时,tarjan 时间复杂度 \(O(n+m)\),bfs \(O(n^2)\) ,将 \(n,m\) 视为同级别,则时间复杂度为 \(O(n^2)\),可以通过此题。


代码:
#include<bits/stdc++.h>
using namespace std;
#define in read()
inline int read(){
int p=0,f=1;
char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){p=p*10+c-'0';c=getchar();}
return p*f;
}
const int N=2e3+5;
const int M=8e3+5;
struct edge{
int v,next;
}e[M];
int head[N],en;
void insert(int u,int v){
e[++en].v=v;
e[en].next=head[u];
head[u]=en;
}
int n,m;
int sta[N],low[N],dfn[N],id[N],sum,sign,top;
bool vis[N];
void dfs(int u){
low[u]=dfn[u]=++sign;
vis[u]=true;sta[++top]=u;
for(int i=head[u];i;i=e[i].next){
int v=e[i].v;
if(!dfn[v]) dfs(v),low[u]=min(low[u],low[v]);
else if(vis[v]) low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
sum++;int i=sta[top--];
while(i!=u){
vis[i]=false;
id[i]=sum;
i=sta[top--];
}
vis[i]=false;
id[i]=sum;
}
}
bool check(){
for(int i=1;i<=n;i++)
if(id[i]==id[i+n])
return false;
return true;
}
struct llmmkk{
int v,next;
}f[M];
int h[N],fn;
void ins(int u,int v){
f[++fn].v=v;
f[fn].next=h[u];
h[u]=fn;
}
bool p[N][N];
int inq[N];
queue<int>q;
void bfs(int s){
memset(inq,0,sizeof(inq));
q.push(s);inq[s]=1;
while(!q.empty()){
int u=q.front();q.pop();p[s][u]=true;
for(int i=h[u];i;i=f[i].next){
int v=f[i].v;
if(!inq[v]) q.push(v);
}
}
}
signed main(){
n=in,m=in;
for(int i=1;i<=m;i++){
int a,b;char ta,tb;
cin>>a>>ta>>b>>tb;
insert(a+(ta=='N')*n,b+(tb=='Y')*n);
insert(b+(tb=='N')*n,a+(ta=='Y')*n);
}
for(int i=1;i<=n<<1;i++)if(!dfn[i])dfs(i);
if(check()){
for(int i=1;i<=n<<1;i++){
for(int j=head[i];j;j=e[j].next){
int v=e[j].v;
if(id[i]!=id[v])ins(id[i],id[v]);
}
}
for(int i=1;i<=n;i++){
int a=id[i],b=id[i+n];
if(!vis[a])bfs(a),vis[a]=1;
if(!vis[b])bfs(b),vis[b]=1;
if(p[a][b]) cout<<'Y';
else if(p[b][a]) cout<<'N';
else cout<<'?';
}
}
else cout<<"IMPOSSIBLE"<<'\n'; return 0;
}
题外话:

一遍过,需要对 2-sat 算法深刻理解,好题!

【BZOJ-2199】奶牛议会的更多相关文章

  1. [BZOJ 2199] 奶牛议会

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2199 [算法] 2-SAT [代码] #include<bits/stdc++ ...

  2. BZOJ 2199: [Usaco2011 Jan]奶牛议会

    2199: [Usaco2011 Jan]奶牛议会 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 375  Solved: 241[Submit][S ...

  3. bzoj 1823: [JSOI2010]满汉全席 && bzoj 2199 : [Usaco2011 Jan]奶牛议会 2-sat

    noip之前学的内容了,看到题竟然忘了怎么建图了,复习一下. 2-sat 大概是对于每个元素,它有0和1两种选择,必须选一个但不能同时选.这之间又有一些二元关系,比如x&y=1等等... 先把 ...

  4. [BZOJ 2199] [USACO11JAN] 大陆议会The Continental Cowngress(2-SAT)

    [BZOJ 2199] [USACO11JAN] 大陆议会The Continental Cowngress(2-SAT) 题面 题面较长,略 分析 考虑把问题转化成一个依赖性问题 我们把每只奶牛投出 ...

  5. C++之路进阶——bzoj2199(奶牛议会)

    F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser  gryz2016 Logout 捐赠本站 Notice:由于本OJ ...

  6. 【BZOJ2199】 [Usaco2011 Jan]奶牛议会

    Description 由于对Farmer John的领导感到极其不悦,奶牛们退出了农场,组建了奶牛议会.议会以“每头牛 都可以获得自己想要的”为原则,建立了下面的投票系统: M只到场的奶牛 (1 & ...

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

    Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 559  Solved: 360[Submit][Status][Discuss] Descriptio ...

  8. BZOJ2199[Usaco2011 Jan]奶牛议会——2-SAT+tarjan缩点

    题目描述 由于对Farmer John的领导感到极其不悦,奶牛们退出了农场,组建了奶牛议会.议会以“每头牛 都可以获得自己想要的”为原则,建立了下面的投票系统: M只到场的奶牛 (1 <= M ...

  9. BZOJ2199 奶牛议会 【2-sat】

    BZOJ2199 奶牛议会 Description 由于对Farmer John的领导感到极其不悦,奶牛们退出了农场,组建了奶牛议会.议会以"每头牛 都可以获得自己想要的"为原则, ...

  10. 【BZOJ2199】[Usaco2011 Jan]奶牛议会 2-SAT

    [BZOJ2199][Usaco2011 Jan]奶牛议会 Description 由于对Farmer John的领导感到极其不悦,奶牛们退出了农场,组建了奶牛议会.议会以“每头牛 都可以获得自己想要 ...

随机推荐

  1. python模块--collections(容器数据类型)

    Counter类(dict的子类, 计数器) 方法 返回值类型 说明 __init__ Counter 传入可迭代对象, 会对对象中的值进行计数, 值为键, 计数为值 .elements() 迭代器 ...

  2. Linux学习笔记--快捷键

    桌面 ALT+空格 打开窗口菜单 ALT+F1 聚焦到桌面左侧任务导航栏,可按上下键导航 ALT+F2     运行命令 ALT+F4 关闭窗口 ALT+TAB 切换程序窗口 PRINT 桌面截图 S ...

  3. Markdown时序图--基础语法

    时序图 ​ 序列图是一种交互图,它显示了流程以何种顺序相互操作. Mermaid可以渲染序列图,如下定义. sequenceDiagram Alice->>John:Message Hel ...

  4. [源码解析] 深度学习分布式训练框架 horovod (21) --- 之如何恢复训练

    [源码解析] 深度学习分布式训练框架 horovod (21) --- 之如何恢复训练 目录 [源码解析] 深度学习分布式训练框架 horovod (21) --- 之如何恢复训练 0x00 摘要 0 ...

  5. POJ3625Building Roads

    Building Roads Description Farmer John had just acquired several new farms! He wants to connect the ...

  6. Django学习day08随堂笔记

    今日考题 """ 今日考题 1.聚合查询,分组查询的关键字各是什么,各有什么特点或者注意事项 2.F与Q查询的功能,他们的导入语句是什么,针对Q有没有其他用法 3.列举常 ...

  7. 对Java的annotation(注解)的认识

    什么是java的annotation(注解) ? 注解的定义(annootation): public @interface TestAnnotation { } 上面的这种形式,便定义了注解是如何定 ...

  8. CentOS8安装ntp实现时间同步

    在CentOS8.0中默认不再支持ntp软件包,时间同步将由chrony来实现,像我这种习惯了ntp同步时间的,一时难以去适应chrony. 本文将通过wlnmp提供的源,来安装ntp服务 添加wln ...

  9. 第一次接触linux系统的你,必须要知道的概念

    linux系统一切皆为文件 linux系统一个多用户系统 没有消息就是好消息 linux系统目录结构 Linux文件系统采用带链接的树形目录结构,即只有一个根目录(通常用"/"表示 ...

  10. 网站优化之mysql优化

    一,网站优化之mysql优化:1.前缀索引,可以通过前缀去识别唯一性,把这个前缀作为索引内容,可以节省存储索引的空间,从而提高索引的查询速度.distinct 排重操作2,2.in条件索引使用同时查询 ...