题目大意:
小 L 计划进行 n 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上
完成游戏。
小 L 的赛车有三辆,分别用大写字母 A、B、C 表示。地图一共有四种,分别用小
写字母 x、a、b、c 表示。其中,赛车 A 不适合在地图 a 上使用,赛车 B 不适合在地
图 b 上使用,赛车 C 不适合在地图 c 上使用,而地图 x 则适合所有赛车参加。适合所
有赛车参加的地图并不多见,最多只会有 d 张。
n 场游戏的地图可以用一个小写字母组成的字符串描述。例如:S=xaabxcbc 表示
小 L 计划进行 8 场游戏,其中第 1 场和第 5 场的地图类型是 x,适合所有赛车,第 2
场和第 3 场的地图是 a,不适合赛车 A,第 4 场和第 7 场的地图是 b,不适合赛车 B,
第 6 场和第 8 场的地图是 c,不适合赛车 C。
小 L 对游戏有一些特殊的要求,这些要求可以用四元组 (i, hi, j, hj) 来描述,表示若
在第 i 场使用型号为 hi 的车子,则第 j 场游戏要使用型号为 hj 的车子。
你能帮小 L 选择每场游戏使用的赛车吗?如果有多种方案,输出任意一种方案。如
果无解,输出 “-1’’(不含双引号)。
思路:
发现x这种型号的赛道很不和谐,然后发现数据范围很小,所以可以考虑
3d
3
d
枚举每一个x赛道的型号。
但是
3dn
3
d
n
显然过不去,其实没有必要枚举3种情况,如果最后答案为
A
A
,那么只有枚举到是会不合法,再任意枚举任意一种都会有解,所以枚举两个就已经够了。
考虑不同的限制该如何连边,对于不存在起点的限制可以直接忽略,对于不存在终点的限制就表示起点是不可以选择的,所以直接这个起点连向同一个集合的另外一个点即可。
然后就转化为了2-SAT模型了,直接连边强连通分量缩点再判断即可。
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;++i)
typedef long long ll;
using namespace std;
void File(){
freopen("uoj317.in","r",stdin);
freopen("uoj317.out","w",stdout);
}
template<typename T>void read(T &_){
T __=0,mul=1; char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')mul=-1;
ch=getchar();
}
while(isdigit(ch))__=(__<<1)+(__<<3)+(ch^'0'),ch=getchar();
_=__*mul;
}
const int maxn=5e4+10;
const int maxm=1e5+10;
const int maxd=8+10;
int n,d,m,ty[maxn],pos[maxd],cnt_d;
char s[maxn];
struct node{int x,t1,y,t2;}lim[maxm];
vector<int>G[maxn*3];
int ty1[maxn],ty2[maxn];
void init(){
read(n); read(d);
scanf("%s",s+1);
REP(i,1,n){
ty[i]=min(s[i]-'a',3);
if(ty[i]==3)pos[++cnt_d]=i;
else{
if(ty[i]==0)ty1[i]=1,ty2[i]=2;
else if(ty[i]==1)ty1[i]=0,ty2[i]=2;
else ty1[i]=0,ty2[i]=1;
}
}
read(m);
REP(i,1,m){
read(lim[i].x);
scanf("%s",s);
lim[i].t1=s[0]-'A';
read(lim[i].y);
scanf("%s",s);
lim[i].t2=s[0]-'A';
}
}
int low[maxn*3],dfn[maxn*3],cnt_dfn,bel[maxn*3],cnt_scc;
stack<int>stk;
void tarjan(int u){
low[u]=dfn[u]=++cnt_dfn;
stk.push(u);
for(int sz=G[u].size()-1,i=0;i<=sz;++i){
int v=G[u][i];
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!bel[v])low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
++cnt_scc;
for(int p=0;p!=u;stk.pop()){
p=stk.top();
bel[p]=cnt_scc;
}
}
}
bool work(){
cnt_dfn=cnt_scc=0;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(bel,0,sizeof(bel));
REP(i,1,n*3)G[i].clear();
REP(i,1,m){
int x=lim[i].x,t1=lim[i].t1,y=lim[i].y,t2=lim[i].t2;
if(t1==ty[x])continue;
else if(t2==ty[y]){
G[x+t1*n].push_back(x+(3-ty[x]-t1)*n);
}
else{
G[x+t1*n].push_back(y+t2*n);
G[y+(3-ty[y]-t2)*n].push_back(x+(3-ty[x]-t1)*n);
}
}
REP(i,1,n){
if(!dfn[i+ty1[i]*n])tarjan(i+ty1[i]*n);
if(!dfn[i+ty2[i]*n])tarjan(i+ty2[i]*n);
}
REP(i,1,n)if(bel[i+ty1[i]*n]==bel[i+ty2[i]*n])return false;
return true;
}
bool dfs(int k){
if(k>d)return work();
REP(i,0,1){
if((double)clock()/CLOCKS_PER_SEC>0.9)return false;
ty[pos[k]]=i;
if(ty[pos[k]]==0)ty1[pos[k]]=1,ty2[pos[k]]=2;
else ty1[pos[k]]=0,ty2[pos[k]]=2;
if(dfs(k+1))return true;
}
return false;
}
int main(){
File();
init();
if(!dfs(1)){
puts("-1");
return 0;
}
REP(i,1,n)if(bel[i+ty1[i]*n]<bel[i+ty2[i]*n])
printf("%c",ty1[i]+'A');
else printf("%c",ty2[i]+'A');
return 0;
}