1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| #include <bits/stdc++.h> using namespace std; const int N = 55,V = 1e4 + 5,M = 2e7 + 5; typedef pair<int,int> pii; #define FI first #define SE second int n,m; char s[N][N]; int tot; namespace TwoSAT { int fir[V],nxt[M],to[M],ect = 1; inline void addedge(int u1,int v1) { nxt[++ect] = fir[u1];fir[u1] = ect;to[ect] = v1; } inline void ins(int u1,int v1) { addedge(u1,v1); u1 = u1 > tot ? u1 - tot : u1 + tot; v1 = v1 > tot ? v1 - tot : v1 + tot; } int dfn[V],low[V],co[V],stk[V],top,col; void tarjan(int x) { dfn[x] = low[x] = ++dfn[0]; stk[++top] = x; for(int i = fir[x],y;y = to[i],i;i = nxt[i]) { if(!dfn[y]) tarjan(y),low[x] = min(low[x],low[y]); else if(!co[y]) low[x] = min(low[x],dfn[y]); } if(low[x] == dfn[x]) { co[x] = ++col; while(stk[top] != x) co[stk[top]] = col,--top; --top; } } inline bool Check() { for(int i = 1;i <= tot + tot;i++) if(!dfn[i]) tarjan(i); for(int i = 1;i <= tot;i++) if(co[i] == co[i + tot]) return 0; return 1; } } int Idh[N][N],Idv[N][N]; pii st[V],ed[V]; bitset<V> can[V]; void dfs(int id,int x) { can[id].set(x); int y = x ^ Idh[st[x].FI][st[x].SE] ^ Idv[st[x].FI][st[x].SE]; if(!can[id][y]) dfs(id,y); y = x ^ Idh[ed[x].FI][ed[x].SE] ^ Idv[ed[x].FI][ed[x].SE]; if(!can[id][y]) dfs(id,y); } int main() { cin >> n >> m; int stx = 0,sty = 0; for(int i = 1;i <= n;i++) for(int j = 1;j <= m;j++) { cin >> s[i][j]; if(s[i][j] == 'O') stx = i,sty = j; } for(int i = 1;i <= n;i++) for(int j = 1;j <= m;j++) if(s[i][j] != '#') { if(j == 1 || s[i][j - 1] == '#') st[++tot] = make_pair(i,j); Idh[i][j] = tot; if(j == m || s[i][j + 1] == '#') ed[tot] = make_pair(i,j); } for(int j = 1;j <= m;j++) for(int i = 1;i <= n;i++) if(s[i][j] != '#') { if(i == 1 || s[i - 1][j] == '#') st[++tot] = make_pair(i,j); Idv[i][j] = tot; if(i == n || s[i + 1][j] == '#') ed[tot] = make_pair(i,j); } for(int i = 1;i <= tot;i++) dfs(i,i); for(int i = 1;i <= tot;i++) if(!can[Idh[stx][sty]][i] && !can[Idv[stx][sty]][i]) TwoSAT::ins(i,i + tot); for(int i = 1;i <= n;i++) for(int j = 1;j <= m;j++) if(s[i][j] == '*') TwoSAT::ins(Idh[i][j] + tot,Idv[i][j]), TwoSAT::ins(Idv[i][j] + tot,Idh[i][j]); for(int i = 1;i <= tot;i++) for(int j = i + 1;j <= tot;j++) if(!can[i][j] && !can[j][i]) TwoSAT::ins(i,j + tot),TwoSAT::ins(j,i + tot); if(TwoSAT::Check()) puts("YES"); else puts("NO"); return 0; }
|