这题可能是(NOI2017)里面最简单的一道题目了吧(目测比蔬菜简单到不知道哪里去了)
考虑看到这种约束条件想(2-SAT),发现我们可以令(u)表示(u)这个点能选的第一个点,(u')表示能选的第二个点。
那么显然有下面的连边:
- 如果(u)的赛道不能够选这个摩的,显然忽略这个限制
- (u)的赛道能选这个,(v)不能选它对应的,那么显然这个限制条件一旦(u)选了这个,那么就GG了。所以连边((u,u'))
- 除此之外,连接((u,v)),((v',u'))
然后直接跑(2-SAT)就行了。
什么?你问我怎么考虑(x)?暴力枚举即可。(只要枚举('a','b')两种情况,因为如果是(c),显然只有((a,c))和((b,c))两种可能,然后之前选(a)和(b)的时候都考虑了,所以不要算(C))
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define re register
#define ll long long
inline int gi(){
int f=1,sum=0;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return f*sum;
}
const int N=100010;
int n,d,m,a[N];char s[N];
struct ques{int u,h1,v,h2;}q[N];
struct node{int to,nxt;}e[N<<1];
int front[N],cnt;
void Add(int u,int v){e[++cnt]=(node){v,front[u]};front[u]=cnt;}
int dfn[N],Time,low[N],in[N],sta[N],top,scc,bl[N];
void Tarjan(int u){
dfn[u]=low[u]=++Time;in[u]=1;sta[++top]=u;
for(int i=front[u];i;i=e[i].nxt){
int v=e[i].to;
if(!dfn[v]){
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(in[v])low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
int v;scc++;
do{
v=sta[top--];bl[v]=scc;in[v]=0;
}while(v!=u);
}
}
int getid(int u,int col){
if(a[u]==col)return 0;
if(!a[u])return u*2+col-1;
if(a[u]==1)return u*2+col/2;
return u*2+col;
}
void solve(){
memset(front,0,sizeof(front));cnt=0;Time=0;memset(dfn,0,sizeof(dfn));
for(int i=1;i<=m;i++){
int x=getid(q[i].u,q[i].h1),y=getid(q[i].v,q[i].h2);
if(x)
if(y)Add(x,y),Add(y^1,x^1);
else Add(x,x^1);
}
for(int i=2;i<=2*n+1;i++)
if(!dfn[i])Tarjan(i);
for(int i=1;i<=n;i++)
if(bl[i*2]==bl[i*2^1])return;
for(int i=1;i<=n;i++){
if(!a[i])printf("%c",bl[i*2]<bl[i*2^1]?'B':'C');
else if(a[i]==1)printf("%c",bl[i*2]<bl[i*2^1]?'A':'C');
else printf("%c",bl[i*2]<bl[i*2^1]?'A':'B');
}
puts("");
exit(0);
}
void dfs(int now){
if(now>n){solve();return;}
if(a[now]==-1){a[now]=0;dfs(now+1);a[now]=1;}
dfs(now+1);
}
char aaa[5],bbb[5];
int main(){
n=gi();d=gi();
for(int i=1;i<=n;i++){
char ch=getchar();int f=0;
while(ch!='a' && ch!='b' && ch!='c' && ch!='x')ch=getchar();
if(ch=='x')f=-1;
else f=ch-'a';
a[i]=f;
}
m=gi();
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%s%d%s",&u,aaa,&v,bbb);
q[i]=(ques){u,aaa[0]-'A',v,bbb[0]-'A'};
}
dfs(1);
puts("-1");
return 0;
}