Face questions
Bzoj2199 (rights issues)
Resolve
Very bare of a 2-sat problem, trouble is how to construct a feasible solution, because the output '?', You can not write the original kind of very short construction method, however I will not dfs method, so he wrote a topological sequence constructor
Or the first tarjan condensing point, it is determined whether there is a feasible solution, there is no direct output, then the presence of stained topology
(NOTE: The next point to point $ J $ $ j '$ they represent a pair, with the order of the magnitude relationship does not exist between the two, is exchangeable)
Consider does not exist '?' Cases, namely the case of an ordinary construction solution. We built a new condensing point of view of the reverse side then stained, for each of the 0 degree point and no staining, we arbitrarily FIG point of a new $ I $ dyeing, dyed color can not be selected, you can then infected with selected colors on its mirror point $ i '$. Explain, if the original point in the new $ J $ I $ $ FIG point in the symmetry point $ j '$ in its mirror point $ i' $ in $ i '$ must be the degree of the 0 and there is no point dyed, accordingly, we can enumerate the original point of $ j $ find something new map $ i $ and $ i '$, and because we built a counter-side, you can not choose the color must be passed to it you can point to, and may be selected from the color can not pass. After performing such staining, a pair of points $ j $ and point $ j '$ there must be a contracted can not choose the color, the other is to choose, you can output the answer
In this problem to consider when to output 'Y' and 'N', apparently when $ j $ can reach $ j 'when $, must be exported $ j' answers $ delegates. We therefore reverse the tarjan built in shrink-point edge, then the point $ j $ and reach the point must not be infected with the election of the mark, and point $ j '$ selectable marker may not play to play, because you must put n of the points after such operations to get all the information, such information is accurate. If there is a pair of points in a point $ j $ infected can not choose the color, the other point of $ j '$ is selected, the output of $ j' $ answer represented; or two points are not stained, output ' ? '; since this time has been to determine whether a solution, so there is no two points have been infected with this case no solution can not choose the color
Code:
#include<cstdio> #include<iostream> #include<vector> #include<algorithm> using namespace std; const int maxn = 1005; int n, m, low[maxn<<1], dfn[maxn<<1], stak[maxn<<1], bel[maxn<<1], vis[maxn<<1], cnt, timer, top; bool col[maxn<<1]; vector<int> G[maxn<<1], H[maxn<<1]; //Y:0, N:One Tarjan (voidint x) { dfn[x] = low[x] = ++timer; stak[++top] = x; vis[x] = 1; for(unsigned int i = 0; i < G[x].size(); ++i) { int id = G[x][i]; if(!dfn[id]) { tarjan(id); low[x] = min(low[x], low[id]); } else if(vis[id]) low[x] = min(low[x], dfn[id]); } if(dfn[x] == low[x]) { cnt ++; int t; do { t = stak[top--]; vis[t] = 0; bel[t] = cnt; } while(t != x); } } void update(int x) { vis[x] = timer; col[x] = 1; for(unsigned int i = 0; i < H[x].size(); ++i) if(vis[H[x][i]] != timer && col[H[x][i]] != 1) update(H[x][i]); } void dfs(int x, int y) { vis[y] = timer; if(bel[(x+n)%(n<<1)] == y) { update(y); return ; } for(unsigned int i = 0; i < H[y].size(); ++i) { int id = H[y][i]; if(vis[id] != timer && col[id] != 1) dfs(x, id); } } int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= m; ++i) { int x, y; char s[2], c[2]; scanf("%d", &x);scanf("%s", s);scanf("%d", &y);scanf("%s", c); if(s[0] == 'Y') { if(c[0] == 'Y') { G[x+n].push_back(y); G[y+n].push_back(x); } else { G[x+n].push_back(y+n); G[y].push_back(x); } } else { if(c[0] == 'N') { G[x].push_back(y+n); G[y].push_back(x+n); } else { G[x].push_back(y); G[y+n].push_back(x+n); } } } for(int i = 1; i <= (n<<1); ++i) if(!dfn[i]) tarjan(i); for(int i = 1; i <= n; ++i) if(bel[i] == bel[i+n]) { printf("IMPOSSIBLE\n"); return 0; } for(int i = 1; i <= (n<<1); ++i) for(unsigned j = 0; j < G[i].size(); ++j) if(bel[G[i][j]] != bel[i]) H[bel[G[i][j]]].push_back(bel[i]); for(int i = 1; i <= n; ++i) { ++timer;dfs(i, bel[i]); ++timer;dfs(i+n, bel[i+n]); } for(int i = 1; i <= n; ++i) { if(!col[bel[i]] && !col[bel[i+n]]) printf("?"); else if(!col[bel[i]]) printf("Y"); else printf("N"); } return 0; }