码迷,mamicode.com
首页 > 其他好文 > 详细

[bzoj4945]游戏

时间:2019-11-27 19:07:49      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:memset   onclick   close   hide   sizeof   --   class   int   amp   

暴力枚举$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

 

[bzoj4945]游戏

标签:memset   onclick   close   hide   sizeof   --   class   int   amp   

原文地址:https://www.cnblogs.com/PYWBKTDA/p/11944225.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!