1. 程式人生 > >【BZOJ4945&&UOJ317】遊戲(2-sat,拓撲序)

【BZOJ4945&&UOJ317】遊戲(2-sat,拓撲序)

題意:

思路:

輸出方案時有一個優秀的性質可以利用:

tarjan縮點之後點所屬的分量編號是原圖的反的拓撲序

所以只需要在兩種方案內找到所屬分量編號較小的那個就行了,用來滿足(i,i')那個限制

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<string>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<map>
  8
#include<set> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned int uint; 14 typedef unsigned long long ull; 15 typedef pair<int,int> PII; 16 typedef vector<int> VI; 17 #define fi first 18 #define se second 19
#define MP make_pair 20 #define N 310000 21 #define M 410000 22 #define eps 1e-8 23 #define pi acos(-1) 24 #define oo 1e9 25 26 int head[M],vet[M],nxt[M],flag[M],dfn[M],low[M],belong[M],stk[M], 27 c[M],x[M],y[M],f[M][2],num[M][4],q[M],b[M],a[M], 28 n,m,D,tot,top,ans,tim,s,id; 29 char
ch[M]; 30 31 void add(int a,int b) 32 { 33 nxt[++tot]=head[a]; 34 vet[tot]=b; 35 head[a]=tot; 36 } 37 38 void tarjan(int u) 39 { 40 flag[u]=1; 41 stk[++top]=u; 42 dfn[u]=low[u]=++tim; 43 int e=head[u]; 44 while(e) 45 { 46 int v=vet[e]; 47 if(!flag[v]) 48 { 49 tarjan(v); 50 low[u]=min(low[u],low[v]); 51 } 52 else if(!belong[v]) low[u]=min(low[u],low[v]); 53 e=nxt[e]; 54 } 55 if(dfn[u]==low[u]) 56 { 57 belong[u]=++id; 58 while(top&&stk[top]!=u) 59 { 60 belong[stk[top]]=id; 61 stk[top--]=0; 62 } 63 stk[top--]=0; 64 } 65 } 66 67 int solve() 68 { 69 70 for(int i=1;i<=s;i++) flag[i]=low[i]=dfn[i]=head[i]=belong[i]=0; 71 tot=0; 72 for(int i=1;i<=m;i++) 73 if(c[x[i]]!=f[i][0]) 74 { 75 if(c[y[i]]==f[i][1]) 76 { 77 int t1=num[x[i]][f[i][0]]; 78 int t2=num[x[i]][6-f[i][0]-c[x[i]]]; 79 add(t1,t2); 80 } 81 else 82 { 83 int t1=num[x[i]][f[i][0]]; 84 int t2=num[y[i]][f[i][1]]; 85 add(t1,t2); 86 t1=num[y[i]][6-c[y[i]]-f[i][1]]; 87 t2=num[x[i]][6-c[x[i]]-f[i][0]]; 88 add(t1,t2); 89 90 } 91 } 92 93 top=tim=id=0; 94 95 for(int i=1;i<=s;i++) 96 if(!flag[i]) tarjan(i); 97 98 99 for(int i=1;i<=n;i++) 100 { 101 int x,y; 102 if(c[i]==1){x=2; y=3;} 103 if(c[i]==2){x=1; y=3;} 104 if(c[i]==3){x=1; y=2;} 105 if(belong[num[i][x]]==belong[num[i][y]]) return 0; 106 } 107 108 for(int i=1;i<=n;i++) 109 { 110 int x,y; 111 if(c[i]==1){x=2; y=3;} 112 if(c[i]==2){x=1; y=3;} 113 if(c[i]==3){x=1; y=2;} 114 int t; 115 if(belong[num[i][x]]<belong[num[i][y]]) t=x; 116 else t=y; 117 printf("%c",'A'+t-1); 118 } 119 return 1; 120 } 121 122 void dfs(int k) 123 { 124 if(ans) return; 125 if(k==D+1) 126 { 127 if(solve()) ans=1; 128 return; 129 } 130 131 for(int i=1;i<=2;i++) 132 { 133 c[b[k]]=i; 134 dfs(k+1); 135 c[b[k]]=0; 136 } 137 } 138 139 int main() 140 { 141 142 scanf("%d%d",&n,&D); 143 scanf("%s",ch+1); 144 for(int i=1;i<=n;i++) 145 { 146 if(ch[i]=='x') a[i]=4; 147 else a[i]=ch[i]-'a'+1; 148 } 149 D=0; 150 for(int i=1;i<=n;i++) 151 if(a[i]==4) b[++D]=i; 152 for(int i=1;i<=n;i++) c[i]=a[i]; 153 154 s=0; 155 for(int i=1;i<=n;i++) 156 for(int j=1;j<=3;j++) num[i][j]=++s; 157 158 scanf("%d",&m); 159 char c1[5]; 160 char c2[5]; 161 for(int i=1;i<=m;i++) 162 { 163 scanf("%d%s%d%s",&x[i],&c1,&y[i],&c2); 164 f[i][0]=c1[0]-'A'+1; 165 f[i][1]=c2[0]-'A'+1; 166 167 } 168 ans=0; 169 dfs(1); 170 if(!ans) printf("-1\n"); 171 return 0; 172 }