[Usaco2011 JAN] cow Assembly The Continental Cowngress - 2-sat (Sequence Topological configured feasible solution)

Face questions

  Bzoj2199 (rights issues)

  Luo Gu P3007

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;
}
View Code

 

Guess you like

Origin www.cnblogs.com/Joker-Yza/p/11306330.html