• [bzoj4945]游戏


    暴力枚举$2^{d}$表示这d个点中一定不选A或一定不选B(那么就包含了所有情况),然后就对原图跑2-sat即可
    注意一个细节,如果某一条限制中初始点不合法,就不用管了;如果最终点不合法,那么相当于初始点不能选,可以用向同类连边的方式来标记一定不能选

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 100005
     4 struct ji{
     5     int nex,to;
     6 }edge[N<<2];
     7 int E,n,m,flag,x[N],y[N],cx[N],cy[N],head[N<<1],vis[N],a[N],bl[N];
     8 char s1[11],s2[11],s[N];
     9 int id(char c,int p){
    10     if (p==c-'a')return -1;
    11     return (2*p>3-(c-'a'));
    12 }
    13 void add(int x,int y){
    14     edge[E].nex=head[x];
    15     edge[E].to=y;
    16     head[x]=E++;
    17     if (E&1)add(y+2*n,x);
    18 }
    19 void dfs1(int k){
    20     if (vis[k])return;
    21     vis[k]=1;
    22     for(int i=head[k];i!=-1;i=edge[i].nex)dfs1(edge[i].to);
    23     a[++a[0]]=k;
    24 }
    25 void dfs2(int k,int s){
    26     if (!vis[k])return;
    27     vis[k]=0;
    28     bl[k]=s;
    29     for(int i=head[k];i!=-1;i=edge[i].nex)dfs2(edge[i].to,s);
    30 }
    31 void dfs(int k){
    32     if (flag)return;
    33     int nex=n+1;
    34     for(int i=n;i>k;i--)
    35         if (s[i]=='x')nex=i;
    36     if (nex>n){
    37         int scc=E=a[0]=0;
    38         memset(head,-1,sizeof(head));
    39         for(int i=1;i<=m;i++){
    40             int xx=id(s[x[i]],cx[i]),yy=id(s[y[i]],cy[i]);
    41             if (xx<0)continue;
    42             if (yy>=0){
    43                 add(2*y[i]+yy-1,2*x[i]+xx-1);
    44                 add(2*x[i]+(xx^1)-1,2*y[i]+(yy^1)-1);
    45             }
    46             else
    47                 for(int j=0;j<3;j++)
    48                     if (id(s[x[i]],j)==(xx^1))add(2*x[i]+(xx^1)-1,2*x[i]+xx-1);
    49         }
    50         for(int i=1;i<=n;i++)dfs1(2*i-1);
    51         for(int i=1;i<=n;i++)dfs1(2*i);
    52         for(int i=1;i<=2*n;i++)head[i]=head[i+2*n];
    53         for(int i=2*n;i;i--)dfs2(a[i],++scc);
    54         for(int i=1;i<2*n;i+=2)
    55             if (bl[i]==bl[i+1])return;
    56         flag=1;
    57         for(int i=1;i<=n;i++)
    58             for(int j=0;j<3;j++)
    59                 if (id(s[i],j)==(bl[2*i-1]>bl[2*i]))printf("%c",'A'+j);
    60         return;
    61     }
    62     s[nex]='a';
    63     dfs(nex);
    64     s[nex]='b';
    65     dfs(nex);
    66     s[nex]='x';
    67 }
    68 int main(){
    69     scanf("%d%*d%s%d",&n,s+1,&m);
    70     for(int i=1;i<=m;i++){
    71         scanf("%d%s%d%s",&x[i],s1,&y[i],s2);
    72         cx[i]=s1[0]-'A';
    73         cy[i]=s2[0]-'A';
    74     }
    75     dfs(0);
    76     if (!flag)printf("-1");
    77 }
    View Code
  • 相关阅读:
    const
    ImportError: No module named google.protobuf
    ImportError: No module named google.protobuf
    多线程同步与单线程异步对比
    多线程同步与单线程异步对比
    再谈select, iocp, epoll,kqueue及各种I/O复用机制
    再谈select, iocp, epoll,kqueue及各种I/O复用机制
    poj1180
    poj3254
    poj3321
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11944225.html
Copyright © 2020-2023  润新知