Cod sursa(job #1155726)

Utilizator PatrikStepan Patrik Patrik Data 27 martie 2014 09:34:39
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.29 kb
    #include<cstdio>
    #include<vector>
    #include<cstring>
    using namespace std;
    #define pb push_back
    #define NMAX 200001
    int N , M , poz[NMAX] , sol[NMAX] , k , p[NMAX] , nr;
    vector<int>G[NMAX] , Gt[NMAX] , CC[NMAX];
    bool u[NMAX];

    void read();
    void solve();
    void write();
    int opus(int nod)
    {
        if(nod <= N)return nod+N;
        return nod-N;
    }
    int abs(int nod)
    {
        if(nod < 0)
            return -nod+N;
        return nod;
    }
    void dfs1(int nod);
    void dfs2(int nod);

    int main()
    {
        read();
        solve();
        write();
        return 0;
    }

    void read()
    {
        int x,y;
        freopen("2sat.in" , "r" , stdin );
        scanf("%d %d" , &N , &M );
        for(int i = 1 ; i<= M ; ++i )
        {
            scanf("%d%d" , &x , &y );
            x = abs(x);
            y = abs(y);
            G[opus(x)].pb(y);
            G[opus(y)].pb(x);
            Gt[y].pb(opus(x));
            Gt[x].pb(opus(y));
        }
    }

    void solve()
    {
        for(int i = 1 ; i<= 2*N ; ++i )
            if(!u[i])
                dfs1(i);
        memset(u,0,sizeof(u));
        for(int i = 2*N ; i ; i-- )
            if(!u[p[i]])nr++,dfs2(p[i]);
        memset(sol,-1,sizeof(sol));

        for(int i = 1 ; i <= N ; ++i )
            if(poz[i] == poz[opus(i)])return;
        for(int i = 1 ; i<= nr ; ++i )
        {
            if(sol[CC[i][0]] != -1)continue;
            for(int j = 0 ; j < (int)CC[i].size() ; ++j )
            {
                sol[CC[i][j]] = 0;
                sol[opus(CC[i][j])] = 1;
            }
        }
    }

    void write()
    {
        freopen("2sat.out" , "w" , stdout );
        if(sol[1] == -1)printf("-1");
        else
            for(int i = 1 ; i<= N ; ++i )
                printf("%d " , sol[i]);
    }

    void dfs1(int nod)
    {
        u[nod] = 1;
        for(int i = 0 ; i < (int) G[nod].size() ; ++i )
            if(!u[G[nod][i]])dfs1(G[nod][i]);
        p[++k] = nod;
    }

    void dfs2(int nod)
    {
        u[nod] = 1;
        CC[nr].pb(nod);
        poz[nod] = nr;
        for(int i = 0 ; i <(int)Gt[nod].size() ; ++i )
            if(!u[Gt[nod][i]])dfs2(Gt[nod][i]);
    }