Pagini recente » Monitorul de evaluare | Monitorul de evaluare | Sandbox | Monitorul de evaluare | Cod sursa (job #826640)
Cod sursa(job #826640)
#include <fstream>
#include <iostream>
#include <vector>
#include <stack>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100005;
struct Ctc{
bool etc1[2 * N], *use;
int etc2[2 * N], *ctc;
vector<int> *graph, *trans;
vector<int> etc3[2 * N];
stack<int> S;
Ctc(){
use = etc1 + N;
ctc = etc2 + N;
trans = etc3 + N;
}
void dfs(int x){
use[x] = true;
for (vector<int> :: iterator it = trans[x].begin() ; it != trans[x].end() ; it++)
if (!use[*it])
dfs(*it);
S.push(x);
}
void dfs(int x, int C){
ctc[x] = C;
use[x] = true;
for (vector<int> :: iterator it = graph[x].begin() ; it != graph[x].end() ; it++)
if (!use[*it])
dfs(*it, C);
}
void compute(int st, int dr){
int nr = 0;
for (int i = st ; i <= dr ; i++)
for (vector<int> :: iterator it = graph[i].begin() ; it != graph[i].end() ; it++)
trans[*it].push_back(i);
memset(etc1, false, sizeof(etc1));
use[0] = true;
for (int i = st ; i <= dr ; i++)
if (!use[i])
dfs(i);
memset(etc1, false, sizeof(etc1));
use[0] = true;
while (!S.empty()){
if (!use[S.top()])
dfs(S.top(), ++nr);
S.pop();
}
}
void get_data(vector<int> *_graph, int st, int dr){
graph = _graph;
compute(st, dr);
}
int* get_ctc(){
return ctc;
}
};
struct TopSort{
vector<int>* graph;
vector<int> ord;
int need[2 * N], size;
TopSort(vector<int>* v, int n){
size = n;
graph = v;
}
void dfs(int x){
--need[x];
ord.push_back(x);
for (vector<int> :: iterator it = graph[x].begin() ; it != graph[x].end() ; it++)
if (!(--need[*it]))
dfs(*it);
}
void get_need(){
for (int i = 1 ; i <= size ; i++)
for (vector<int> :: iterator it = graph[i].begin() ; it != graph[i].end() ; it++)
need[*it]++;
}
void compute(){
get_need();
for (int i = 1 ; i <= size ; i++)
if (!need[i])
dfs(i);
}
vector<int> top_sort(){
compute();
return ord;
}
};
struct Sat{
vector<int> etc1[2 * N], *graph;
vector<int> tree[2 * N], negate[2 * N];
int etc2[2 * N], *ctc;
int val[2 * N], nrC, size;
bool use[2 * N], okay;
Ctc A;
Sat(){
graph = etc1 + N;
ctc = etc2 + N;
nrC = 0;
okay = true;
}
void unalloc(vector<int>& v){
vector<int> a;
a.swap(v);
}
void push(int x, int y){
graph[-x].push_back(y);
graph[-y].push_back(x);
}
void copy(int* a, int* b){
for (int i = -size ; i <= size ; i++)
a[i] = b[i];
}
void add(vector<int>& tree, vector<int>& v, int x){
for (vector<int> :: iterator it = v.begin() ; it != v.end() ; it++)
if (ctc[*it] != x)
tree.push_back(ctc[*it]);
}
void arrange(vector<int>& v){
vector<int> a;
sort(v.begin(), v.end());
for (vector<int> :: iterator it = v.begin() ; it != v.end() ; it++)
if (a.empty() || a.back() != *it)
a.push_back(*it);
v.swap(a);
}
void get_ctc(){
A.get_data(graph, -size, size);
copy(ctc, A.get_ctc());
for (int i = -size ; i <= size ; i++)
if (nrC < ctc[i])
nrC = ctc[i];
}
void build_tree(){
for (int i = -size ; i <= size ; i++)
add(tree[ ctc[i] ], graph[i], ctc[i]);
for (int i = 1 ; i <= nrC ; i++)
arrange(tree[i]);
}
void dfs(int x, bool stts){
if (use[x]){
if (val[x] != stts)
okay = false;
return;
}
use[x] = true;
val[x] = stts;
for (vector<int> :: iterator it = negate[x].begin() ; it != negate[x].end() ; it++)
dfs(*it, !stts);
if (!stts)
return;
for (vector<int> :: iterator it = tree[x].begin() ; it != tree[x].end() ; it++)
dfs(*it, stts);
}
vector<int> top_sort(){
TopSort T(tree, size);
return T.top_sort();
}
void compute(){
get_ctc();
build_tree();
for (int i = 1 ; i <= size ; i++){
negate[ ctc[i] ].push_back(ctc[-i]);
negate[ ctc[-i] ].push_back(ctc[i]);
}
vector<int> v = top_sort();
memset(use, false, sizeof(use));
for (vector<int> :: iterator it = v.begin() ; it != v.end() ; it++)
if (!use[*it])
dfs(*it, false);
}
vector<int> get_sat(){
compute();
vector<int> v;
if (!okay){
v.push_back(-1);
return v;
}
for (int i = 1 ; i <= size ; i++)
v.push_back( val[ ctc[i] ] );
return v;
}
} S;
ifstream in("2sat.in");
ofstream out("2sat.out");
int main(){
int m, x, y;
in >> S.size >> m;
while (m--){
in >> x >> y;
S.push(x, y);
}
vector<int> v = S.get_sat();
for (vector<int> :: iterator it = v.begin() ; it != v.end() ; it++)
out << (*it) << " ";
out << "\n";
return 0;
}