两个元素编号1,2,拆出两个点3,4。
如果连边4→2,2→3。
跑完强连通分量之后四个点的编号分别为1,3,2,4。
Id1<Id3,Id2<Id4。
所以两个元素都为0。。。
这是我代码的过程。但事实上3→2连边后元素1应该为1,但按照算法流程输出0求助。
#include<bits/stdc++.h>
#define N 100005
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define pre(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
int n,d,m;char u[N],s[N];
int h[N],tot,kt='A'-'a';
struct edge{
int to,nxt;
}e[N<<1];
void add(int x,int y){
cout<<x<<" "<<y<<endl;
e[++tot].nxt=h[x];h[x]=tot;e[tot].to=y;
}
int dfn[N],low[N],sta[N],top,idx,v[N],cnt,col[N];
void dfs(int x){
dfn[x]=low[x]=++idx;sta[++top]=x;v[x]=1;
for(int i=h[x];i;i=e[i].nxt){
if(!dfn[e[i].to])dfs(e[i].to),low[x]=min(low[x],low[e[i].to]);
else if(v[e[i].to])low[x]=min(low[x],dfn[e[i].to]);
}
if(low[x]==dfn[x]){
++cnt;while(true){
int y=sta[top--];
v[y]=0;col[y]=cnt;
if(x==y)return ;
}
}
}
struct node{
int i,j;char x[2],y[2];
}a[N];
int calc(int x,char op){
if(s[x]=='a'&&op=='B')return x;
if(s[x]=='b'&&op=='A')return x;
if(s[x]=='c'&&op=='A')return x;
return x+n;
}
bool check(int rc){
rep(i,1,n)if(u[i]=='x')s[i]='a'+(rc&1),rc>>=1;else s[i]=u[i];
puts(s+1);
memset(dfn,0,sizeof(dfn));memset(v,0,sizeof(v));
memset(h,0,sizeof(h));tot=top=idx=cnt=0;
rep(op,1,m){
if(a[op].x[0]==s[a[op].i]+kt){continue;}
else if(a[op].y[0]==s[a[op].j]+kt){
int yy,xx=calc(a[op].i,a[op].x[0]);
if(xx>n)yy=xx-n;else yy=xx+n;
add(xx,yy);
}
else{
add(calc(a[op].i,a[op].x[0]),calc(a[op].j,a[op].y[0]));
}
}
rep(i,1,n<<1)if(!dfn[i])dfs(i);
rep(i,1,n)if(col[i]==col[i+n])return false;
rep(i,1,n<<1)printf("%d ",col[i]);putchar('\n');
rep(i,1,n)
if(col[i]<col[i+n]){ // i=2
if(s[i]=='a')putchar('B');
else putchar('A');
}
else{ // i=1
cout<<"ss"<<endl;
if(s[i]=='c')putchar('B');
else putchar('C');
}
return true;
}
int main(){
scanf("%d%d",&n,&d);
scanf("%s",u+1);
scanf("%d",&m);
rep(i,1,m)scanf("%d%s%d%s",&a[i].i,a[i].x,&a[i].j,a[i].y);
int bas=(1<<d)-1;
rep(i,0,bas)if(check(i))return 0;
puts("-1");
return 0;
}