Cod sursa(job #1649789)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 11 martie 2016 15:06:29
Problema Andrei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.89 kb
#include <fstream>
#include <vector>

using namespace std;

class InputReader {
    public:
        InputReader() {}
        InputReader(const char *file_name) {
            input_file = fopen(file_name, "r");
            cursor = 0;
            fread(buffer, SIZE, 1, input_file);
        }
        inline InputReader &operator >>(int &n) {
            while(buffer[cursor] < '0' || buffer[cursor] > '9') {
                advance();
            }
            n = 0;
            while('0' <= buffer[cursor] && buffer[cursor] <= '9') {
                n = n * 10 + buffer[cursor] - '0';
                advance();
            }
            return *this;
        }
    private:
        FILE *input_file;
        static const int SIZE = 1 << 17;
        int cursor;
        char buffer[SIZE];
        inline void advance() {
            ++ cursor;
            if(cursor == SIZE) {
                cursor = 0;
                fread(buffer, SIZE, 1, input_file);
            }
        }
};

const int NMAX = 100005;

//12:23
vector <int> graph[2 * NMAX];
vector <int> graph_inv[2 * NMAX];

#define graph (graph + NMAX)
#define graph_inv (graph_inv + NMAX)

void add_edge(int a, int b) {
    graph[-a].push_back(b);
    graph[-b].push_back(a);

    graph_inv[a].push_back(-b);
    graph_inv[b].push_back(-a);
}

int h[2 * NMAX];

bool vis[3 * NMAX];
#define vis (vis + NMAX)

int pos;

void dfs_inv(int node) {
    vis[node] = true;
    for (auto it: graph_inv[node])
        if (!vis[it])
            dfs_inv(it);
    h[++ pos] = node;
}

int which_comp[2 * NMAX];
#define which_comp (which_comp + NMAX)

void dfs(int node, int comp) {
    vis[node] = true;
    which_comp[node] = comp;
    for (auto it: graph[node])
        if (!vis[it])
            dfs(it, comp);
}

int col[2 * NMAX];

int main()
{
    InputReader cin("andrei.in");
    ofstream cout("andrei.out");

    int n, m = 0;
    cin >> n >> m;

    int a, b, type;
    while (m --) {
        cin >> a >> b >> type;

        if (type == 0)
            add_edge(a, b);
        else if (type == 1)
            add_edge(-a, -b);
        else {
            add_edge(-a, b);
            add_edge(-b, a);
        }
    }

    for (int i = -n; i <= n; ++ i)
        if (i && !vis[i])
            dfs_inv(i);

    for (int i = -n; i <= n; ++ i)
        vis[i] = 0;

    int comp = 0;
    for (int i = pos; i; -- i)
        if (!vis[h[i]])
            dfs(h[i], ++ comp);

    for (int i = 1; i <= comp; ++ i)
        vis[i] = 0;

    for (int i = pos; i; -- i)
        if (!vis[which_comp[h[i]]]) {
            vis[which_comp[h[i]]] = true;
            vis[which_comp[-h[i]]] = true;
            col[which_comp[h[i]]] = 1;
        }

    for (int i = 1; i <= n; ++ i)
        cout << col[which_comp[i]] << " \n"[i == n];

    //cin.close();
    cout.close();
    return 0;
}