[Noi2017]游戏

来源:互联网 发布:搜不到网络打印机 编辑:程序博客网 时间:2024/06/16 04:13

2-SAT的题啦
考虑到x很小,我们只需要暴力枚举x是什么就好了,然后每个点就两种状态,2-SAT模型啦!
总的复杂度O(3dn)
然后呢,建图的时候,将一些边建好,剩下的与x有关的到时候再建,可以减少很多复杂度。。要不可能会超。。但是uoj的数据一般般,不这么做也行,然后bzoj根本就没有spj

然后我这个写法不是哪里出了一点点小问题,uoj95分,还有一个点WA了。。看了半天,很绝望。。
我又不想写spj,于是对拍也不大好。。就这样吧,估计也就是一点点细节问题。。
就这样吧,但我觉得方法是没有问题啊,大家可以借鉴哈!但抄代码就别了。。

#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>#include<queue>using namespace std;const int N=50005*2;const int M=100005*2;int n,d,m;char ss[N];struct qq{    int i,hi;    int j,hj;}s[M];int read (){    char ch=getchar();int x=0;    while (ch<'0'||ch>'9')  ch=getchar();    while (ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}    return x;}int read1 (){    char ch=getchar();    while (ch!='A'&&ch!='B'&&ch!='C') ch=getchar();    return ch-'A'+1;}struct qy{    int x,y,last;}e[M];int num,last[N];void init (int x,int y){    num++;    e[num].x=x;e[num].y=y;    e[num].last=last[x];    last[x]=num;}int a[N];int P (int x,int y)//在x这个地方填y的编号 {    if (a[x]==y) return -1;    int cnt=0;    for (int u=1;u<=3;u++)    {        if (a[x]==u) continue;        if (u==y) break;        cnt++;    }    return cnt*n+x;}bool tf=false;int dfn[N],low[N],belong[N],cnt,sta[N],lalal,shen;bool in[N];int mymin (int x,int y){return x<y?x:y;}void dfss (int x){    dfn[x]=low[x]=++lalal;    sta[++cnt]=x;    in[x]=true;    for (int u=last[x];u!=-1;u=e[u].last)    {        int y=e[u].y;        if (dfn[y]==-1)        {            dfss(y);            low[x]=mymin(low[x],low[y]);        }        else if (in[y]) low[x]=mymin(dfn[y],low[x]);    }    if (low[x]==dfn[x])    {        shen++;        int now;        do        {            now=sta[cnt--];            belong[now]=shen;            in[now]=false;        }while (now!=x);    }}qy e1[M];int num1,last1[N];int du[N];void init1 (int x,int y){    du[y]++;    num1++;    e1[num1].x=x;e1[num1].y=y;    e1[num1].last=last1[x];    last1[x]=num1;}void rebt (){    num1=0;memset(last1,-1,sizeof(last1));    for (int u=1;u<=2*n;u++)        for (int i=last[u];i!=-1;i=e[i].last)        {            int y=e[i].y;            if (belong[u]!=belong[y])                init1(belong[y],belong[u]);        }}int op[N];int col[N];void dfs1 (int x){    if (col[x]!=0) return ;    col[x]=2;    for (int u=last1[x];u!=-1;u=e1[u].last)    {        int y=e1[u].y;        dfs1(y);    }}void topsort (){    queue<int> q;    for (int u=1;u<=shen;u++)        if (du[u]==0) q.push(u);    while (!q.empty())    {        int x=q.front();q.pop();        //printf("%d",x);        if (col[x]!=0) continue;        col[x]=1;dfs1(op[x]);        for (int u=last1[x];u!=-1;u=e1[u].last)        {            int y=e1[u].y;            du[y]--;            if (du[y]==0) q.push(y);        }    }}void print (int x,int y){    //printf("%d %d %d\n",x,y,a[x]);    int cnt=0;    for (int u=1;u<=3;u++)    {        if (a[x]==u) continue;        cnt++;        if (cnt==y)         {            printf("%c",u+'A'-1);            break;        }    }}void check ()//当前这个序列有没有一个合法方案 {    num=0;memset(last,-1,sizeof(last));    for (int u=1;u<=m;u++)    {        int x=P(s[u].i,s[u].hi),y=P(s[u].j,s[u].hj);        if (x==-1) continue;        if (y==-1) init(x,(x+n)%(2*n));        else {init(x,y);init((y+n)%(2*n),(x+n)%(2*n));}    }    memset(dfn,-1,sizeof(dfn));    memset(in,false,sizeof(in));    shen=lalal=cnt=0;    for (int u=1;u<=2*n;u++)        if (dfn[u]==-1)            dfss(u);    for (int u=1;u<=n;u++)        if (belong[u]==belong[u+n])            return ;/*  printf("%d %d\n",a[1],a[2]);    for (int u=1;u<=m;u++)    {        int x=P(s[u].i,s[u].hi),y=P(s[u].j,s[u].hj);    //  if (x==-1) continue;        printf("YES:%d %d\n",x,y);        /*if (y==-1) init(x,(x+n)%(2*n));        init(x,y);    }*///  for (int u=1;u<=num;u++) printf("%d %d\n",e[u].x,e[u].y);     tf=true;    memset(du,0,sizeof(du));    rebt();    for (int u=1;u<=n;u++)    {        op[belong[u]]=  belong[u+n];        op[belong[u+n]]=belong[u];    }    memset(col,0,sizeof(col));    /*for (int u=1;u<=2*n;u++) printf("%d ",[u]);    printf("\n");    for (int u=1;u<=num1;u++) printf("%d %d\n",e1[u].x,e1[u].y);*/    topsort();//  for (int u=1;u<=2*n;u++) printf("%d ",col[u]);    for (int u=1;u<=n;u++)        if (col[belong[u]]==1)  print(u,1);        else print(u,2);}void dfs (int x)//到哪一位了{    if (tf) return ;    if (x>n) {check();return ;}    if (ss[x]=='x')    {        a[x]=1;dfs(x+1);        a[x]=2;dfs(x+1);        a[x]=3;dfs(x+1);    }    else     {        a[x]=ss[x]-'a'+1;        dfs(x+1);    }}int main(){    scanf("%d%d",&n,&d);    scanf("%s",ss+1);    scanf("%d",&m);    for (int u=1;u<=m;u++)    {        s[u].i=read();s[u].hi=read1();        s[u].j=read();s[u].hj=read1();    }    dfs(1);    if (tf==false) printf("-1");/*  if (tf) printf("YES\n");    else printf("NO\n");*/    return 0;}