Pagini recente » Cod sursa (job #1001560) | Cod sursa (job #192228) | Cod sursa (job #963380) | Cod sursa (job #1675524) | Cod sursa (job #1851198)
/**
* Worg
*/
#include <stack>
#include <cstdio>
#include <vector>
#include <algorithm>
using std::min;
using std::stack;
using std::vector;
FILE *fin = freopen("2sat.in", "r", stdin);
FILE *fout = freopen("2sat.out", "w", stdout);
const int MAX_N = 1 + 100000;
const int MAX_NODES = (MAX_N << 1);
/*-------- Input data --------*/
int N, M;
int total_nodes;
/*-------- Graph data --------*/
vector< int > graph[MAX_NODES];
int index[MAX_NODES], lowlink[MAX_NODES], where[MAX_NODES];
int current_index = 1;
bool in_stack[MAX_NODES];
stack< int > my_stack;
vector< int > current_scc;
vector< vector<int> > scc_list;
int node_value[MAX_NODES];
/*-------- --------*/
int OppositeNode(int node) {
if(node > N) {
return node - N;
} else {
return node + N;
}
}
void ReadInput() {
scanf("%d%d", &N, &M);
total_nodes = 2 * N;
for(int i = 1; i <= M; i++) {
int x, y; scanf("%d%d", &x, &y);
x = (x < 0) ? (-x + N) : (x);
y = (y < 0) ? (-y + N) : (y);
graph[OppositeNode(x)].push_back(y);
graph[OppositeNode(y)].push_back(x);
}
}
void StrongConnect(int node) {
// printf("%d\n", node);
index[node] = lowlink[node] = current_index; // Initializam datele pentru nodul curent
current_index ++;
my_stack.push(node); in_stack[node] = true;
for(int next_node : graph[node]) {
if(!index[next_node]) {
StrongConnect(next_node);
lowlink[node] = min(lowlink[node], lowlink[next_node]);
} else if(in_stack[next_node]){
lowlink[node] = min(lowlink[node], index[next_node]);
}
}
if(lowlink[node] == index[node]) { // Am dat peste o noua componenta tare conexa
current_scc.clear();
int current_node;
do {
current_node = my_stack.top(); my_stack.pop();
in_stack[current_node] = false; current_scc.push_back(current_node);
where[current_node] = (int)scc_list.size();
}while(current_node != node); // Continuam pana dam peste nodul tata
scc_list.push_back(current_scc);
}
}
void RunTarjan() {
for(int i = 1; i <= total_nodes; i++) {
if(!index[i]) {
StrongConnect(i);
}
}
}
bool GiveValues() {
bool possible = true;
for(int i = 1; i <= total_nodes; i++) {
if(where[i] == where[OppositeNode(i)]) {
possible = false; // Daca un nod si negatia lui sunt in aceeasi componenta, atunci nu avem solutie
}
node_value[i] = -1;
}
for(vector< int > scc : scc_list) {
bool ok = true;
for(int node : scc) {
if(node_value[node] == 0) {
ok = false; break;
}
}
if(ok) { // Putem face toate nodurile din componenta curenta sa aiba valoarea 1, iar opusele valoarea 0
for(int node : scc) {
node_value[node] = 1;
node_value[OppositeNode(node)] = 0;
}
} else { // Altfel facem toate nodurile sa aiba valoarea 0
for(int node : scc) {
node_value[node] = 0;
}
}
}
return possible;
}
void WriteOutput() {
for(int i = 1; i <= N; i++) {
printf("%d ", node_value[i]);
}
}
void OutputSccList() {
for(vector< int > scc : scc_list) {
for(int node : scc) {
printf("%d %d;", node, where[node]);
}
printf("\n");
}
}
int main() {
ReadInput();
RunTarjan();
// OutputSccList(); /** CAREFUL ! */
if(GiveValues()) {
WriteOutput();
} else {
printf("-1\n");
}
return 0;
}