Pagini recente » Cod sursa (job #834919) | Cod sursa (job #2148215) | Cod sursa (job #588792) | Cod sursa (job #1516092) | Cod sursa (job #1456900)
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <list>
#include <vector>
#include <cassert>
using namespace std;
#define MAXN 100010
template<class T> class jmenvect : public vector<T> {
public:
T& operator[](int n) {
if (n > 0)
return this->at(n);
else
return this->at(-n + (size() >> 1));
}
};
class graph {
private:
vector< list<int> > adiac;
vector< list<int> > neg_adiac;
public:
graph();
graph(int);
int size();
void newnod();
void newedge(int, int);
const list<int>& getList(int);
void rev_DFS(int, jmenvect<int>&, jmenvect<int>&);
bool SCC_DFS(int, int, jmenvect<int>&);
};
graph::graph() {
adiac.reserve(MAXN);
neg_adiac.reserve(MAXN);
}
graph::graph(int n) {
adiac.resize(n + 1);
neg_adiac.resize(n + 1);
}
int graph::size() {
return adiac.size();
}
void graph::newnod() {
neg_adiac.resize(size() + 1);
adiac.resize(size() + 1);
}
void graph::newedge(int n1, int n2) {
if (n1 > 0)
adiac[n1].push_back(n2);
else
neg_adiac[-n1].push_back(n2);
}
const list<int>& graph::getList(int n) {
if (n > 0)
return adiac[n];
else
return neg_adiac[-n];
}
void graph::rev_DFS(int nod, jmenvect<int>& visited, jmenvect<int> &finished) {
auto L = this->getList(-nod);
visited[nod] = 1;
for (auto i = L.begin(); i != L.end(); ++i)
if (!visited[-(*i)])
rev_DFS(-(*i), visited, finished);
finished.push_back(nod);
}
bool graph::SCC_DFS(int curComp, int nod, jmenvect<int>& visited) {
visited[nod] = curComp;
auto L = this->getList(nod);
for (auto i = L.begin(); i != L.end(); ++i) {
if (!visited[*i]) {
if (!SCC_DFS(curComp, *i, visited))
return false;
}
}
if (visited[-nod])
return false;
visited[-nod] = -curComp;
return true;
}
pair<jmenvect<int>, int> korasaju(graph* G) {
int N = G->size() - 1;
jmenvect<int> visisted;
visisted.resize((N << 1) + 1);
jmenvect<int> finished;
finished.reserve((N << 1) + 1);
for (int i = 1; i <= N; i++) {
if (!visisted[i])
G->rev_DFS(i, visisted, finished);
if (!visisted[-i])
G->rev_DFS(-i, visisted, finished);
}
visisted.assign((N << 1) + 1, 0);
int curComp = 0;
for (auto i = finished.rbegin(); i != finished.rend() - 1; ++i) {
curComp++;
if (!visisted[*i]) {
if (!G->SCC_DFS(curComp, *i, visisted)) {
jmenvect<int> dummyvect;
return{ dummyvect, 0 };
}
}
else
curComp--;
}
return{ visisted, curComp };
}
int main() {
assert(freopen("2sat.in", "r", stdin));
assert(freopen("2sat.out", "w", stdout));
int N, M;
scanf("%d%d", &N, &M);
graph* G = new graph(N);
for (int i = 0; i < M; i++) {
int a, b;
scanf("%d%d", &a, &b);
G->newedge(-a, b);
G->newedge(-b, a);
}
pair<jmenvect<int>, int> p = korasaju(G);
jmenvect<int>& SCC = p.first;
if (!SCC.size()) {
printf("-1\n");
return 0;
}
int nrComp = p.second;
jmenvect<char> cval;
cval.resize((nrComp << 1) + 1);
for (int i = 1; i <= nrComp; i++) {
cval[-i] = 0;
cval[i] = 1;
}
for (int i = 1; i <= N; i++)
printf("%d ", cval[SCC[i]]);
printf("\n");
return 0;
}