| 12
 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;
 }
 
 |