传送门

果然图论的题永远建图最麻烦……看着题解代码的建图过程真的很珂怕……

先不考虑地图$x$,那么每一个地图都只能用两种赛车,于是我们可以用2-SAT来搞,用$i$表示这个地图能用的第一辆车,$i'$表示它能用的第二辆车

至于怎么连边呢,考虑限制条件$(i,h_i,j,h_j)$,如果$i$不能用$h_i$我们直接忽视这个限制条件,如果$j$不能用$h_j$说明无解,于是我们连边$(i,i')$表示如果选了$i$的第一辆车就无解

否则的话就按一般的2-SAT把上面的限制条件连边即可

然后考虑怎么处理地图$x$,因为$d$最大只有$8$,且可行的方案里每一个地图$x$只要用一辆车,于是我们考虑枚举每一个地图$x$哪一辆车不能用,只需要枚举$A$和$B$即可,如果有解,能用$BC$和能用$AC$的方案里一定有一个可行

于是时间复杂度就是$O((n+m)2^d)$

 //minamoto
#include<iostream>
#include<cstdio>
#include<cstring>
#define mem(a) (memset(a,0,sizeof(a)))
#define swap(x,y) (x^=y^=x^=y)
#define neg(x) (x>n?x-n:x+n)
using namespace std;
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getchar()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getchar());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
inline char getc(){
char ch;while((ch=getchar())!='A'&&ch!='B'&&ch!='C');return ch;
}
const int N=2e5+;
int head[N],Next[N],ver[N],tot;
inline void add(int u,int v){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
}
int dfn[N],low[N],bl[N],st[N],num,cnt,top,n,m,d;
void tarjan(int u){
dfn[u]=low[u]=++num,st[++top]=u;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(!dfn[v]) tarjan(v),cmin(low[u],low[v]);
else if(!bl[v]) cmin(low[u],dfn[v]);
}
if(dfn[u]==low[u]) for(++cnt;st[top+]!=u;--top) bl[st[top]]=cnt;
}
inline void clear(){
mem(head),mem(dfn),mem(bl),mem(st);
tot=num=cnt=;
}
int a1[N],b1[N],Sooke[N];char s[N],a2[N],b2[N],QAQ[N];
int flag=;
int tran(int x,char ch){
if(s[x]=='a') return ch=='B'?x:x+n;
if(s[x]=='b'||s[x]=='c') return ch=='A'?x:x+n;
if(ch=='C') return x+n;return x;
}
bool solve(){
clear();
for(int i=;i<=m;++i)
if(s[a1[i]]!='x'&&s[b1[i]]!='x'){
if(a2[i]==s[a1[i]]-) continue;
int u=tran(a1[i],a2[i]),v;
if(b2[i]==s[b1[i]]-){add(u,neg(u));continue;}
v=tran(b1[i],b2[i]),add(u,v),add(neg(v),neg(u));
}else{
char o=s[a1[i]],p=s[b1[i]];
int u,v,x=Sooke[a1[i]],y=Sooke[b1[i]];
if(o=='x'&&p=='x'){
if(a2[i]==QAQ[x]) continue;
u=tran(a1[i],a2[i]);
if(b2[i]==QAQ[y]){add(u,neg(u));continue;}
v=tran(b1[i],b2[i]),add(u,v),add(neg(v),neg(u));
}else if(o=='x'&&p!='x'){
if(a2[i]==QAQ[x]) continue;
u=tran(a1[i],a2[i]);
if(b2[i]==s[b1[i]]-){add(u,neg(u));continue;}
v=tran(b1[i],b2[i]),add(u,v),add(neg(v),neg(u));
}else{
if(a2[i]==s[a1[i]]-) continue;
u=tran(a1[i],a2[i]);
if(b2[i]==QAQ[y]){add(u,neg(u));continue;}
v=tran(b1[i],b2[i]),add(u,v),add(neg(v),neg(u));
}
}
for(int i=,l=n<<;i<=l;++i) if(!dfn[i]) tarjan(i);
for(int i=;i<=n;++i) if(bl[i]==bl[i+n]) return ;
for(int i=;i<=n;++i)
if(bl[i]<bl[i+n]){
if(s[i]=='a') putchar('B');
else if(s[i]=='b'||s[i]=='c') putchar('A');
else if(QAQ[Sooke[i]]=='A') putchar('B');
else putchar('A');
}else{
if(s[i]=='a'||s[i]=='b') putchar('C');
else if(s[i]=='c') putchar('B');
else if(QAQ[Sooke[i]]=='A') putchar('C');
else putchar('B');
}
return ;
}
void dfs(int dep){
if(dep>d){
if(!flag) flag=solve();
if(flag) exit();
return;
}
QAQ[dep]='A',dfs(dep+);
QAQ[dep]='B',dfs(dep+);
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),read();
scanf("%s",s+),m=read();
for(int i=;i<=n;++i) if(s[i]=='x') Sooke[i]=++d;
for(int i=;i<=m;++i)
a1[i]=read(),a2[i]=getc(),b1[i]=read(),b2[i]=getc();
dfs();
if(!flag) printf("%d",-);
return ;
}

最新文章

  1. xib文件的加载方法
  2. 把crosswalk打包到cordova项目中
  3. 前端一:走进HTML
  4. python RabbitMQ队列/redis
  5. Java堆栈的应用2----------中缀表达式转为后缀表达式的计算Java实现
  6. 一些android系统参数的获取
  7. C#保留小数位数
  8. poj 1523 求割点
  9. win向linux传文件
  10. java输入输出流(内容练习)
  11. docke镜像上传到dockerhub仓库和阿里云docker仓库的方法
  12. 团队作业4——第一次项目冲刺 FiRsT DaY
  13. 在LwIP 协议栈移植 Snap 7
  14. 深入理解ajax
  15. Android弹出Toast工具类总结
  16. HBase底层存储原理
  17. MQ的demo
  18. Ubuntu 搭建docker registry 私有仓库
  19. doGet和doPost区别
  20. Yii 初识

热门文章

  1. jQuery Ajax Post Data Example
  2. 设计模式之命令模式(Command)摘录
  3. 让 Logo &quot;飞&quot; 出屏幕
  4. LeetCode题解(13)--Roman to Integer
  5. POJ 1183 反正切函数的应用(数学代换,基本不等式)
  6. object-c iOS 教程 git for mac
  7. asp.net+access实现DropDownList与RadDatePicker同步筛选
  8. MapReduce算法形式五:TOP—N
  9. 主线程 view
  10. css 中的伪类选择器before 与after