[NOI2017] 游戏

news/2024/9/12 23:20:14/文章来源:https://www.cnblogs.com/dingxingdi/p/18373511

先来讲一下到底什么叫K-SAT

先来看看2-SAT的准确定义

image

那么对于k-SAT,不是说每个集合就有\(k\)个元素了(每个集合仍然只有两个元素,因为布尔变量的取值只有\(0\)\(1\)),而是说给出的限制条件涉及\(k\)个元素,比如3-SAT

image

那么对于这道题目,如果不考虑\(\text{x}\)的话,就是一个裸的2-SAT问题;发现\(d\)很小,考虑\(\text{x}\)的话,枚举即可(由于也要让\(\text{x}\)只包含两个元素,所以是枚举的不能用哪一类型的赛车)。具体见这篇题解

但是要讲一下细节

一.最好先将每个地图可以用的赛车类型用字符串存下来(按字典序排序),比如pt[i]="AB"表示第\(i\)个地图可以用的赛车类型为\(A\)\(B\),然后在加边的时候,再去判断是\(i\)还是\(i+n\),要简单很多

二.不要用STL,用手写栈

三.如果对每个\(\text{x}\)枚举三种情况的话,理论复杂度就会炸掉,这个时候就要思考能不能只枚举两种情况,另外一种情况已经被包含了

四.也是卡常新操作:将链式前向星清空一部分。我们枚举的时候,每一次都要情况链式前向星的话,常熟太大了;此时我们可以先将所有不涉及\(\text{x}\)的边全部加入,然后在枚举的时候不删除这些边,只删除新加入的边(涉及\(\text{x}\)的边)即可

#include<bits/stdc++.h>
using namespace std;
const int N=5e4+10,M=1e5+10;
int n,m,d;
int visitime;
int dfn[N<<1],low[N<<1];
int pos[10];
int s[N<<1],tp;
char S[N];
bool instack[N<<1];
string pt[N];
int scc;
int belong[N<<1];
int cnt,Cnt;
int End[M<<2],Last[N<<1],Next[M<<2];
int num,edge[M];
int u[M],v[M];
char a[M],b[M];
void add(int x,int y)
{End[++Cnt]=y,Next[Cnt]=Last[x],Last[x]=Cnt;
}
void tarjan(int u)
{dfn[u]=low[u]=++visitime;s[++tp]=u;instack[u]=1;for(int i=Last[u];i;i=Next[i]){int v=End[i];if(!dfn[v]){tarjan(v);low[u]=min(low[u],low[v]);}else if(dfn[v]&&instack[v]){low[u]=min(low[u],dfn[v]);}} if(low[u]==dfn[u]){++scc;int v;do{v=s[tp--];instack[v]=0;belong[v]=scc;}while(v!=u);}
}
void del(int x)
{Cnt--;Last[x]=Next[Last[x]];
}
int main()
{bool mark=0;scanf("%d%d",&n,&d);scanf("%s",S);for(int i=1;i<=n;i++)switch(S[i-1]){case 'a':pt[i]="BC";break;case 'b':pt[i]="AC";break;case 'c':pt[i]="AB";break;case 'x':pos[++cnt]=i;break;//pos记录每个x的位置 } scanf("%d",&m);for(int i=1;i<=m;i++)scanf("%d %c%d %c\n",&u[i],&a[i],&v[i],&b[i]);for(int i=1;i<=m;i++)if(S[u[i]-1]!='x'&&S[v[i]-1]!='x'){if(pt[u[i]][0]==a[i]){if(pt[v[i]][0]==b[i]) add(u[i],v[i]),add(v[i]+n,u[i]+n);else if(pt[v[i]][1]==b[i]) add(u[i],v[i]+n),add(v[i],u[i]+n);else add(u[i],u[i]+n);}else if(pt[u[i]][1]==a[i]){if(pt[v[i]][0]==b[i]) add(u[i]+n,v[i]),add(v[i]+n,u[i]);else if(pt[v[i]][1]==b[i]) add(u[i]+n,v[i]+n),add(v[i],u[i]);else add(u[i]+n,u[i]);}}else edge[++num]=i;for(int i=0;i<(1<<cnt);i++){visitime=scc=0;tp=0;for(int j=1;j<=(n<<1);j++) dfn[j]=low[j]=instack[j]=belong[j]=0;for(int j=1;j<=cnt;j++)switch(i>>(j-1)&1){case 0:pt[pos[j]]="BC";break;case 1:pt[pos[j]]="AC";break;} for(int k=1,j=edge[k];k<=num;k++,j=edge[k])if(pt[u[j]][0]==a[j]){if(pt[v[j]][0]==b[j]) add(u[j],v[j]),add(v[j]+n,u[j]+n);else if(pt[v[j]][1]==b[j]) add(u[j],v[j]+n),add(v[j],u[j]+n);else add(u[j],u[j]+n);}else if(pt[u[j]][1]==a[j]){if(pt[v[j]][0]==b[j]) add(u[j]+n,v[j]),add(v[j]+n,u[j]);else if(pt[v[j]][1]==b[j]) add(u[j]+n,v[j]+n),add(v[j],u[j]);else add(u[j]+n,u[j]);}for(int j=1;j<=(n<<1);j++)if(!dfn[j]) tarjan(j);bool flag=1;for(int j=1;j<=n;j++)if(belong[j]==belong[j+n]){flag=0;break;}for(int k=1,j=edge[k];k<=num;k++,j=edge[k])//删边操作,想一下为什么成立 if(pt[u[j]][0]==a[j]){if(pt[v[j]][0]==b[j]) del(u[j]),del(v[j]+n);else if(pt[v[j]][1]==b[j]) del(u[j]),del(v[j]);else del(u[j]);}else if(pt[u[j]][1]==a[j]){if(pt[v[j]][0]==b[j]) del(u[j]+n),del(v[j]+n);else if(pt[v[j]][1]==b[j]) del(u[j]+n),del(v[j]);else del(u[j]+n);}if(!flag) continue; mark=1;for(int j=1;j<=n;j++)printf("%c",belong[j]>belong[j+n]?pt[j][1]:pt[j][0]);break;}if(!mark) puts("-1");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/785325.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【待做】【整理】【域渗透系列】跨森林:Extra SID攻击

本文选自《内网安全攻防:红队之路》 由于微软将森林信任设计为安全边界,在默认情况下,即使我们完全控制了当前森林,也可能无法入侵其他受信任的森林(trusted forest)。 下面介绍在非默认条件下(但也比较常见),如何入侵一个受信任的森林。 在《内网安全攻防:渗透测试实…

织梦dedecms主页在哪个文件

DedeCMS的首页模板文件位置:/templets/default/index.html。其中default文件夹是默认的,如果你用的是其他模版,在后台可以查看的,进入后台>系统>系统基本参数>模板默认风格,后面的default就是当前使用的模板,首页文件就在这里面。 织梦内容管理系统(DedeCms) 以…

织梦DedeCMS关键词怎么替换

//高亮专用, 替换多次是可能不能达到最多次 function _highlight($string, $words, $result, $pre) {global $cfg_replace_num;$string = str_replace(", ", $string);uasort($words,create_function($a, $b,return strlen($a)>strlen($b);));扫码添加技术【解决问…

结构开发笔记(五):solidworks软件(四):绘制36x36方块摄像头基座

前言绘制36x36方块摄像头模型中的方块摄像头。  本篇描述详细绘制方法。 摄像头结构 绘制摄像头结构分析结构零件分为三块区域,线绘制固定底座,对应区域2   绘制方块摄像头步骤一:新建零件打开软件  创建零件:  步骤二:绘制固定底座的底座拉伸凸台,选择上视基准面…

RSS 教程完结

完结撒花🎉🎉🎉完结撒花🎉🎉🎉 都到了 4202 年了,居然还有人在用 RSS,甚至还有人在写 RSS 教程,真是不可思议🤔 就先写到这了,当然如果有新学到什么技巧,或看到一些好用的 RSS 阅读器,也还是会更新的。 参考了无数的文章/教程,才有了本系列教程,非常感谢…

【待做】【整理】【横向移动】探测 存活主机篇

免责声明 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使用者本人负责。本文所提供的工具仅用…

Prometheus+Grafana监控Mysql数据库

安装配置 Prometheus是Go语言编写的,所以仅依赖二进制编译库,从官网根据操作系统下载对应的二进制库:https://prometheus.io/download/ 解压到/usr/local/prometheus目录下 tar -xzvf prometheus-2.45.2.linux-amd64.tar.gz mv prometheus-2.45.2.linux-amd64 /usr/local/pr…

1-数据操作数据

torch.cat操作广播机制tensor和numpy的转换对NA数据的处理

SOA架构开发小助手PAVELINK.SOA-Converter V1.4.2新版本发布

PAVELINK.SOA-Converter转换工具,用于衔接基于SOA的控制器设计、开发及测试过程中所常见的各类软件工具。PAVELINK.SOA-Converter能提供IDL及服务矩阵等文件的语法及规则检查,自动化完成多种不同格式IDL文件之间的转换,以及其它常用的各类型格式文件转换。PAVELINK.SOA-Conv…

Mysql锁查看

查看InnoDB的锁情况 SHOW ENGINE INNODB STATUS;命令会返回一个包含详细InnoDB引擎状态的报告,其中包含当前锁的详细信息。在输出的 LATEST DETECTED DEADLOCK 部分找到死锁信息,并在 TRANSACTIONS 部分找到当前的锁等待信息。 查看 MyISAM 锁情况 -- 方法一: 查看表锁 SHOW …

GPT4SM论文阅读笔记

Are GPT Embeddings Useful for Ads and Recommendation?论文阅读笔记 Abstract 现存的问题: ​ 尽管 LLMs 潜力巨大,但关于其文本嵌入是否能帮助广告和推荐服务的讨论却十分有限。 提出方法: ​ 为了探索 GPT 嵌入在广告和推荐中的应用,我们提出了三种策略,将 LLMs 的知…

题解:P10892 SDOI2024

题解:P10892 SDOI2024 题目传送门 题目思路 通过阅读题面,我们可以看出,其实对于每一次纠结,如果交出了 \(\frac{n-1}{2}\) 只猫猫,则剩下的为 \(\frac{n+1}{2}\) 只猫猫;如果交出了 \(\frac{n+1}{2}\) 只猫猫,则剩下的为 \(\frac{n-1}{2}\) 只猫猫。 为了使纠结的次数尽…