Группа сталкивается на вопросы четырех юаней \ ((я, h_i, J , h_j) \) ограничивают выбор моделей автомобилей, не трудно думать об этом вопросе использования \ (2-SAT \) для решения.
Рассмотрим преобразуются в \ (2-СБ \) модель, обнаружили , что в дополнение к карте \ (х \) , другие карты только две модели автомобилей могут участвовать, а затем положить обе модели на два государства.
Если \ (S_i = А \) , то состояние \ (В \) и \ (С \) .
Если \ (S_i = В \) , то состояние \ (А \) и \ (С \) .
Если \ (S_i = С \) , то состояние \ (А \) и \ (В \) .
Обсуждение затем четыре-кортеж, множество \ (I \) является состояние входа, \ (^ I \ Prime \) в другое состояние.
Если раздел \ (I \) поле, \ (h_i \) отсутствует, не выполняется даже края.
Если раздел \ (I \) поле, \ (h_i \) есть в наличии, в \ (J \) поле, \ (h_j \) не доступен из \ (I \) к \ (я ^ \ простое \) даже со стороны, представляет собой не выбран \ (I \) .
Если оба доступны, с \ (I \) к \ (J \) связное края, указывает на то, когда выберите \ (I \) , то следует выбрать \ (J \) , в то время как \ (J ^ \ простое \) к \ (я ^ \ простые \) , связанные ребра, если не представлены здесь выбран \ (J \) , не обязательно выбирают из группы \ (I \) .
Продолжать рассматривать как иметь дело с картой \ (х- \) , показал , что число \ (d \ leqslant8 \) , размер данных мало, то мы можем использовать \ (ДФС \) , чтобы перечислить все возможные случаи снова, а затем проверить , является ли законны.
Нам нужно только рассмотреть отображение \ (х \) эквивалентна карте \ (а \) и карты \ (Ь \) в обоих случаях, так как в это время включен \ (A, B, C \ ) три модели.
Сложность Время \ (О (2 ^ О (п-т +)) \) .
Тем не менее найти многие детали реализации, ясно увидеть код.
\(код:\)
#include<bits/stdc++.h>
#define maxn 1000010
using namespace std;
template<typename T> inline void read(T &x)
{
x=0;char c=getchar();bool flag=false;
while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
if(flag)x=-x;
}
int n,d,m,x_cnt;
bool flag;
char s[maxn],a[5],b[5],c1[maxn],c2[maxn];
int pos[maxn];
struct node
{
int x,y;
char a,b;
}t[maxn];
struct edge
{
int to,nxt;
}e[maxn];
int head[maxn],edge_cnt;
void add(int from,int to)
{
e[++edge_cnt]=(edge){to,head[from]};
head[from]=edge_cnt;
}
int dfn_cnt,co_cnt,top;
int dfn[maxn],low[maxn],co[maxn],st[maxn];
bool vis[maxn];
void tarjan(int x)
{
dfn[x]=low[x]=++dfn_cnt;
st[++top]=x;
vis[x]=true;
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(!dfn[y])
{
tarjan(y);;
low[x]=min(low[x],low[y]);
}
else if(vis[y])
low[x]=min(low[x],dfn[y]);
}
if(low[x]==dfn[x])
{
co_cnt++;
int now;
do
{
now=st[top--];
vis[now]=false;
co[now]=co_cnt;
}while(now!=x);
}
}
bool check()
{
for(int i=1;i<=2*n;++i)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=n;++i)
if(co[i]==co[i+n])
return false;
return true;
}
void clear()
{
edge_cnt=dfn_cnt=co_cnt=top=0;
memset(st,0,sizeof(st));
memset(co,0,sizeof(co));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(vis,0,sizeof(vis));
memset(head,0,sizeof(head));
}
void work()
{
clear();
for(int i=1;i<=m;++i)
{
int x=t[i].x,y=t[i].y;
char a=t[i].a,b=t[i].b;
if(s[x]==a) continue;
if(s[y]==b)
{
add(x+(a==c2[x])*n,x+(a==c1[x])*n);
continue;
}
add(x+(a==c2[x])*n,y+(b==c2[y])*n);
add(y+(b==c1[y])*n,x+(a==c1[x])*n);
}
if(check())
{
flag=true;
for(int i=1;i<=n;i++)
{
if(co[i]<co[i+n]) printf("%c",c1[i]);
else printf("%c",c2[i]);
}
}
}
void dfs(int x)
{
if(flag) return;
if(x==d+1)
{
work();
return;
}
int now=pos[x];
s[now]='A',c1[now]='B',c2[now]='C',dfs(x+1);
s[now]='B',c1[now]='A',c2[now]='C',dfs(x+1);
}
int main()
{
read(n),read(d);
scanf("%s",s+1);
for(int i=1;i<=n;++i)
{
s[i]+='A'-'a';
if(s[i]=='A') c1[i]='B',c2[i]='C';
if(s[i]=='B') c1[i]='A',c2[i]='C';
if(s[i]=='C') c1[i]='A',c2[i]='B';
if(s[i]=='X') pos[++x_cnt]=i;
}
read(m);
for(int i=1;i<=m;++i)
{
read(t[i].x),scanf("%s",a),read(t[i].y),scanf("%s",b);
t[i].a=a[0],t[i].b=b[0];
}
dfs(1);
if(!flag) printf("-1");
return 0;
}