NOI2017游戏

2SAT

写挂again

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define N 50010
  4 #define M 100010
  5 #define IL inline
  6 #define RG register 
  7 #define INF (1<<30)
  8 IL bool isitdigit(char c){    return c<='9'&&c>='0';    }
  9 IL bool isitalpha(char c){    return c>='a'&&c<='z';    }
 10 IL bool isitalphas(char c){    return c>='A'&&c<='Z';    }
 11 IL int minify(int &a,int b){    return a<b? a:a=b;    }
 12 IL int read()
 13 {
 14     RG int s;RG char c;
 15     while(!isitdigit(c=getchar()));
 16     for(s=c-'0';isitdigit(c=getchar());s=(s<<1)+(s<<3)+c-'0');
 17     return s;
 18 }
 19 IL char readchar()
 20 {
 21     RG char c;
 22     while(!isitalpha(c=getchar()));
 23     return c;
 24 }
 25 IL char readchars()
 26 {
 27     RG char c;
 28     while(!isitalphas(c=getchar()));
 29     return c;
 30 }
 31 int n,m,d;
 32 int color[M],trans[N],ord[N][5],another[M][4],anothertot,uncertain[10],uncertaintot,backup[M];
 33 int head[2][M],to[10*M],nxt[10*M],tot;
 34 int inde,up[M],num[M];
 35 int st[M],top,belong[M],cnt,que[M],front,tail,du[M],vis[M];
 36 int opsite[M];
 37 IL void addedge(int d,int f,int t)
 38 {
 39     to[++tot]=t;
 40     nxt[tot]=head[d][f];
 41     head[d][f]=tot;
 42 }
 43 void tarjan(int i)
 44 {
 45     up[i]=num[i]=++inde;st[++top]=i;
 46     for(RG int j=head[0][i];j;j=nxt[j]) 
 47         if(!num[to[j]]) 
 48         {
 49             tarjan(to[j]);
 50             minify(up[i],up[to[j]]);
 51         }
 52         else if(!belong[to[j]])
 53             minify(up[i],num[to[j]]);
 54     if(num[i]==up[i])
 55     {
 56         cnt++;
 57         for(;st[top]!=i;--top) belong[st[top]]=cnt;
 58         belong[st[top]]=cnt;
 59         top--;
 60     }
 61 }
 62 IL bool judge()
 63 {
 64     for(RG int i=1;i<=n;++i)
 65         if(belong[i]==belong[i+n]) return 1;
 66     for(RG int i=1;i<=n+n;++i)
 67     {
 68         for(RG int j=head[0][i];j;j=nxt[j]) 
 69             if(belong[i]!=belong[to[j]])
 70                 addedge(1,belong[i],belong[to[j]]),du[belong[to[j]]]++;
 71     }
 72     return 0;
 73 }
 74 IL void topsort()
 75 {
 76     memset(que,0,sizeof(que));
 77     tail=0;front=1;
 78     for(RG int i=1;i<=cnt;++i) if(!du[i]) que[++tail]=i;
 79     while(front<=tail)
 80     {
 81         int i=que[front++];
 82         for(RG int j=head[1][i];j;j=nxt[j])
 83         {
 84             du[to[j]]--;
 85             if(!du[to[j]]) que[++tail]=to[j];
 86         }
 87     }
 88 }
 89 void dfs(int i)
 90 {
 91     vis[i]=-1;
 92     for(RG int j=head[1][i];j;j=nxt[j])
 93         if(!vis[to[j]])    dfs(to[j]);
 94 }
 95 void print()
 96 {
 97     memset(opsite,0,sizeof(opsite));
 98     for(RG int i=1;i<=n;++i) opsite[belong[i]]=belong[i+n];
 99     for(RG int i=n;i<=n+n;++i) opsite[belong[i]]=belong[i-n];
100     for(RG int i=1;i<=tail;i++)
101     {
102         if(!vis[que[i]])
103         {
104             vis[que[i]]=1;
105             dfs(opsite[que[i]]);
106         }
107     }
108     for(RG int i=1;i<=n;++i)
109             printf("%c",vis[belong[i]]==1? color[i]:color[i+n]);
110 }
111 int main()
112 {
113     freopen("2017game.in","r",stdin);
114     freopen("2017game.out","w",stdout);
115     n=read(),d=read();
116     for(int ope=1;ope<=n;++ope)
117     {
118         RG char s=readchar();
119         if(s=='x') 
120         {
121             uncertain[++uncertaintot]=ope;
122             continue;
123         }
124         if(s=='a')
125         {
126             ord[ope]['B'-'A']=ope;color[ope]='B';
127             ord[ope]['C'-'A']=ope+n;color[ope+n]='C';
128             trans[ope]='B'+'C'-'A';
129         }
130         else if(s=='b')
131         {
132             ord[ope]['A'-'A']=ope;color[ope]='A';
133             ord[ope]['C'-'A']=ope+n;color[ope+n]='C';
134             trans[ope]='A'+'C'-'A';
135         }
136         else
137         {
138             ord[ope]['A'-'A']=ope;color[ope]='A';
139             ord[ope]['B'-'A']=ope+n;color[ope+n]='B';
140             trans[ope]='A'+'B'-'A';
141         }
142     }
143     m=read();
144     while(m--)
145     {
146         RG int i=read();RG char hi=readchars();RG int j=read();RG char hj=readchars();
147         if(!trans[i]||!trans[j]) 
148         {
149             another[++anothertot][0]=i,another[anothertot][1]=hj,another[anothertot][2]=j,another[anothertot][3]=hj;
150             continue;
151         }
152         if(!ord[j][hj-'A']&&ord[i][hi-'A'])
153             addedge(0,ord[i][trans[i]-hi],ord[i][hi-'A']);
154         else if(ord[j][hj-'A']&&ord[i][hi-'A'])
155         {
156             addedge(0,ord[j][hj-'A'],ord[i][hi-'A']);
157             if(i!=j) addedge(0,ord[i][trans[i]-hi],ord[j][trans[j]-hj]);
158         }
159     }
160     for(int i=1;i<=n;++i) backup[i]=head[0][i],backup[i+n]=head[0][i+n];
161     RG int still=tot+1;
162     for(RG int i=0;i<=(1<<uncertaintot)-1;++i)
163     {    
164         memset(head[1],0,sizeof(head[1]));
165         memset(up,0,sizeof(up));
166         memset(num,0,sizeof(num));
167         memset(st,0,sizeof(st));
168         memset(belong,0,sizeof(belong));
169         memset(du,0,sizeof(du));
170         memset(vis,0,sizeof(vis));
171         cnt=top=inde=0;
172         for(RG int j=1;j<=n;++j) head[0][j]=backup[j],head[0][j+n]=backup[j+n];
173         while(tot>=still)    to[tot]=nxt[tot]=0,tot--;
174         for(RG int j=1;j<=uncertaintot;++j) 
175             if(i&(1<<(j-1)))
176             {
177                 ord[uncertain[j]]['B'-'A']=uncertain[j];color[uncertain[j]]='B';
178                 ord[uncertain[j]]['C'-'A']=uncertain[j]+n;color[uncertain[j]+n]='C';
179                 ord[uncertain[j]]['A'-'A']=0;
180                 trans[uncertain[j]]='B'+'C'-'A';
181             }
182             else
183             {
184                 ord[uncertain[j]]['A'-'A']=uncertain[j];color[uncertain[j]]='A';
185                 ord[uncertain[j]]['B'-'A']=uncertain[j]+n;color[uncertain[j]+n]='B';
186                 ord[uncertain[j]]['C'-'A']=0;
187                 trans[uncertain[j]]='A'+'B'-'A';
188             }
189         for(RG int j=1;j<=anothertot;++j) 
190             if(!ord[another[j][2]][another[j][3]-'A']&&ord[another[j][0]][another[j][1]-'A'])
191                 addedge(0,ord[another[j][0]][trans[another[j][0]]-another[j][1]],ord[another[j][0]][another[j][1]-'A']);
192             else if(ord[another[j][2]][another[j][3]-'A']&&ord[another[j][0]][another[j][1]-'A'])
193             {
194                 addedge(0, ord[another[j][2]][another[j][3]-'A'],ord[another[j][0]][another[j][1]-'A']);
195                 addedge(0,ord[another[j][0]][trans[another[j][0]]-another[j][1]],ord[another[j][2]][trans[another[j][2]]-another[j][3]]);
196             }
197         for(RG int j=1;j<=n+n;++j) if(!num[j]) tarjan(j);
198         if(judge()) continue;
199         topsort();
200         print();
201         return 0;
202     }
203     printf("-1");
204     return 0;
205 }        

 

转载于:https://www.cnblogs.com/MediocreKonjac/p/9174377.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值