Cod sursa(job #1017469)

Utilizator tzipleatudTudor Tiplea tzipleatud Data 27 octombrie 2013 19:49:53
Problema Andrei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.3 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <stack>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <set>
#define NM 200010

using namespace std;

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

int N, M, K;
int MinLevel[NM], Level[NM], Component[NM];
int In[NM];
int Simetric[NM];
bool Value[NM];
vector<int> G[NM], NG[NM];
bool InStack[NM], Removed[NM];
stack<int> S;
queue<int> Q;

int Negate (int x)
{
    return (x<=N?x+N:x-N);
}

void Build (int x, int y)
{
    G[Negate(x)].push_back(y);
    G[Negate(y)].push_back(x);
}

void Read ()
{
    int x, y, z;
    f >> N >> M;
    for (int i=1; i<=M; i++)
    {
        f >> x >> y >> z;
        if (z==0)
            Build(Negate(x), Negate(y));
        if (z==1)
            Build(x, y);
        if (z==2)
        {
            Build(x, Negate(y));
            Build(Negate(x), y);
        }
    }
    M=0;

    f.close();
}

void DoTarjan (int node)
{
    Level[node]=MinLevel[node]=++K;
    S.push(node);
    InStack[node]=1;

    for (vector<int>::iterator it=G[node].begin(); it!=G[node].end(); ++it)
    {
        if (!Level[*it])
        {
            DoTarjan(*it);
            MinLevel[node]=min(MinLevel[node], MinLevel[*it]);
            continue;
        }
        if (InStack[*it])
            MinLevel[node]=min(MinLevel[node], Level[*it]);
    }

    if (Level[node]==MinLevel[node])
    {
        ++M;
        for (bool ok=1; ok && !S.empty(); S.pop())
        {
            InStack[S.top()]=0;
            Component[S.top()]=M;
            if (S.top()==node) ok=0;
        }
    }
}

void BuildComp ()
{
    for (int i=1; i<=2*N; i++)
        if (!Level[i])
            DoTarjan(i);

    for (int i=1; i<=2*N; i++)
    {
        for (vector<int>::iterator it=G[i].begin(); it!=G[i].end(); ++it)
            if (Component[i]!=Component[*it])
                NG[Component[i]].push_back(Component[*it]);
        G[i].clear();
        G[i].swap(G[i]);
    }

    for (int i=1; i<=2*N; i++)
    {
        if (Component[i]==Component[Negate(i)])
        {
            g << -1 << '\n';
            g.close();
            exit(0);
        }

        Simetric[Component[i]]=Component[Negate(i)];
    }

    for (int i=1; i<=M; i++)
    {
        sort(NG[i].begin(), NG[i].end());
        NG[i].resize(unique(NG[i].begin(), NG[i].end())-NG[i].begin());
        NG[i].swap(NG[i]);

        for (vector<int>::iterator it=NG[i].begin(); it!=NG[i].end(); ++it)
            In[*it]++;
    }
}

void Solve ()
{
    for (int i=1; i<=M; i++)
        if (In[i]==0)
            Q.push(i);

    while (!Q.empty())
    {
        int node=Q.front();
        Q.pop();

        Removed[node]=1;
        Removed[Simetric[node]]=1;
        Value[node]=0;
        Value[Simetric[node]]=1;

        for (vector<int>::iterator it=NG[node].begin(); it!=NG[node].end(); ++it)
            if (!Removed[*it])
            {
                --In[*it];
                if (In[*it]<=0)
                    Q.push(*it);
            }
    }
}

void Print ()
{
    for (int i=1; i<=N; i++)
        g << 1-Value[Component[i]] << ' ';

    g.close();
}

int main ()
{
    Read();
    BuildComp();
    Solve();
    Print();

    return 0;
}