Cod sursa(job #1161674)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 31 martie 2014 13:20:16
Problema Andrei Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.66 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

const int Nmax = 100000;

vector <int> G[2 * Nmax + 1], GT[Nmax + 1];
int sol[2 * Nmax + 1], vis[2 * Nmax + 1], postorder[2 * Nmax + 1];

int N, M, P;

int neg( int x )
{
    if ( x > N )
            return x - N;
    else
            return x + N;
}

void DFS( int nod )
{
    vis[nod] = 1;

    for ( auto x: G[nod] )
            if ( !vis[x] )
                    DFS( x );

    postorder[ ++P ] = nod;
}

void DFST( int nod )
{
    if ( sol[nod] ) cout<<"ERROR";

    sol[ neg( nod ) ] = 1;
    vis[nod] = 0;

    for ( auto x: GT[nod] )
            if ( vis[x] )
                    DFST( x );
}

void Kosaraju_Sharir()
{
    for ( int i = 1; i <= 2 * N; ++i )
            if ( !vis[i] )
                    DFS( i );

    for ( int i = P; i >= 1; i-- )
    {
        if ( vis[ postorder[i] ] && vis[ neg( postorder[i] ) ] )
                DFST( postorder[i] );
    }
}

void add_edge( int x, int y )
{
    G[neg(x)].push_back(y);
    GT[y].push_back(neg(x));

    G[neg(y)].push_back(x);
    GT[x].push_back(neg(y));
}

int main()
{
    ifstream f("andrei.in");
    ofstream g("andrei.out");

    f >> N >> M;

    for ( int i = 1, x, y, c; i <= M; ++i )
    {
        f >> x >> y >> c;

        switch( c )
        {
            case 0: add_edge( x, y ); break;
            case 1: add_edge( neg( x ), neg( y ) ); break;
            case 2: add_edge( neg( x ), y ); add_edge( x, neg( y ) ); break;
        }
    }

    Kosaraju_Sharir();

    for ( int i = 1; i <= N; ++i )
            g << sol[i] << " ";

    return 0;
}