Cod sursa(job #467159)

Utilizator toni2007Pripoae Teodor Anton toni2007 Data 28 iunie 2010 12:23:59
Problema Andrei Scor 0
Compilator cpp Status done
Runda Stelele Informaticii 2010, clasele X-XII, Ziua 2 Marime 4.05 kb
#include <stdio.h>
#include <assert.h>
#include <vector>
#include <bitset>
#include <map>
#include <queue>
#include <utility>
#include <algorithm>

using namespace std;

#define val(x)		(x < 0) ? (-x + N) : x
#define forI(it,v)	for (vector <int> :: iterator it = v.begin(); it != v.end(); ++ it)
#define maxN 		500100

vector < pair <int, int> > List;
int variables, expressions;
vector <int> var_adj[maxN], var_adj_t[maxN], vtc(maxN), value(maxN, -1), scc_in_deg(maxN, 0);
vector < vector <int> > sccs;
bitset <maxN> viz;
int Color[maxN], nr_componente, N, M;
vector <int> GG[maxN], Culoare_muchie[maxN];

inline int abs(const int x) {
    return (x < 0) ? -x : +x;
}

inline int idx(const int x) {
    return (x < 0) ? abs(x) + variables : x;
}

inline int non(const int x) {
    return (x > variables) ? x - variables : x + variables;
}

void DFP(int n, vector <int>& used, vector <int>& discover) {
    vector <int>::iterator it;
    used[n] = 1;
    for (it = var_adj[n].begin(); it != var_adj[n].end(); ++ it) 
        if (!used[*it])
            DFP(*it, used, discover);
    discover.push_back(n);
}

void DFM(int n, vector <int>& used, vector <int>& scc) {
    vector <int>::iterator it;
    used[n] = 1;
    scc.push_back(n);
    for (it = var_adj_t[n].begin(); it != var_adj_t[n].end(); ++ it) 
        if (!used[*it])
            DFM(*it, used, scc);
}

void compute_sccs(void) {
    vector <int> used(maxN), discover, scc;

    used.assign(used.size(), 0);
    for (int i = 1; i <= variables * 2; ++ i) 
        if (!used[i]) 
            DFP(i, used, discover);
    used.assign(used.size(), 0);
    vector <int>::reverse_iterator it;
    for (it = discover.rbegin(); it != discover.rend(); ++ it) {
        if (!used[*it]) {
            scc.clear();
            DFM(*it, used, scc);
            for (vector <int>::iterator it2 = scc.begin(); it2 != scc.end(); ++ it2)
                vtc[*it2] = sccs.size();
            sccs.push_back(scc);
        }
    }
}

int main(void) {
	int i, a, b, c, j;

	freopen("andrei.in", "r", stdin);
	freopen("andrei.out", "w", stdout);

	scanf("%d%d", &N, &M);

	for (i = 1; i <= M; ++ i) {
		scanf("%d %d%d", &a, &b, &c);
		if (c == 0)
			List.push_back(make_pair(a,b));
		else if (c == 1)
			List.push_back(make_pair(-a, -b));
		else {
			List.push_back(make_pair(a, b));
			List.push_back(make_pair(-a, -b));
		}
	}
	
	variables = N;
	
    for (int i = 0; i < (int) List.size(); ++ i) {
        int x, y;
		x = List[i].first; y = List[i].second;
        var_adj[non(idx(x))].push_back(idx(y));
        var_adj_t[idx(y)].push_back(non(idx(x)));
        var_adj[non(idx(y))].push_back(idx(x));
        var_adj_t[idx(x)].push_back(non(idx(y)));
    }
    compute_sccs();

    int impossible = false;
    for (int x = 1; x <= variables; ++ x) {
        if (vtc[x] == vtc[x + variables])
            impossible = true;
    }

    if (!impossible) {
        for (int x = 1; x <= variables * 2; ++ x) {
            vector <int>::iterator it;
            for (it = var_adj[x].begin(); it != var_adj[x].end(); ++ it)
                if (vtc[x] != vtc[*it])
                    scc_in_deg[ vtc[*it] ] ++;
        }
        queue <int> Q;
        for (int idx = 0; idx < (int) sccs.size(); ++ idx) {
            if (scc_in_deg[idx] == 0)
                Q.push(idx);
        }
        while (!Q.empty()) {
            int idx = Q.front();
            Q.pop();
            vector <int>::iterator it, i, j;
            for (it = sccs[idx].begin(); it != sccs[idx].end(); ++ it) {
                int x = (*it > variables) ? *it - variables : *it;
                if (value[x] == -1)
                    value[x] = (*it <= variables) ? 0 : 1;
            }
            for (i = sccs[idx].begin(); i != sccs[idx].end(); ++ i) {
                for (j = var_adj[*i].begin(); j != var_adj[*i].end(); ++ j)
                    if (vtc[*i] != vtc[*j]) {
                        if ((-- scc_in_deg[ vtc[*j] ]) == 0)
                            Q.push(vtc[*j]);
                    }
            }
        }
		for (i = 1; i <= N; ++ i)
			printf("%d ", value[i]);
    }
    else
        assert(false);
    return 0;
}