Pagini recente » Cod sursa (job #1999552) | Cod sursa (job #2044235) | Cod sursa (job #1730906) | Cod sursa (job #2844110) | Cod sursa (job #2787068)
#include <algorithm>
#include <fstream>
#include <stack>
#include <unordered_map>
#include <vector>
using namespace std;
struct Node {
vector<int> edges;
int time = -1;
int low = -1;
int comp = -1;
bool in_stack = false;
bool value = false;
};
struct Graph {
vector<Node> nodes;
Graph(int vars);
int Size() const;
void AddCond(int a, int b);
Node& operator[](int index);
const Node& operator[](int index) const;
private:
int RealIndex(int var) const;
};
Graph::Graph(int vars) : nodes(2 * vars, Node{}) {
}
int Graph::Size() const {
return nodes.size();
}
void Graph::AddCond(int a, int b) {
nodes[RealIndex(-a)].edges.push_back(b);
nodes[RealIndex(-b)].edges.push_back(a);
}
Node& Graph::operator[](int index) {
return nodes[RealIndex(index)];
}
const Node& Graph::operator[](int index) const {
return nodes.at(RealIndex(index));
}
int Graph::RealIndex(int var) const {
if (var > 0) {
return var - 1;
}
return nodes.size() + var;
}
void Extract(Graph& graph, int end_node, stack<int>& st, vector<int>& order) {
static auto id = 0;
id += 1;
while (order.empty() || order.back() != end_node) {
auto node = st.top();
st.pop();
graph[node].in_stack = false;
graph[node].comp = id;
order.push_back(node);
}
}
void Dfs(Graph& graph, int node, stack<int>& st, vector<int>& order) {
static auto time = 0;
graph[node].time = graph[node].low = (time += 1);
st.push(node);
graph[node].in_stack = true;
for (const auto& next : graph[node].edges) {
if (graph[next].time == -1) {
Dfs(graph, next, st, order);
graph[node].low = min(graph[node].low, graph[next].low);
}
if (graph[next].in_stack) {
graph[node].low = min(graph[node].low, graph[next].time);
}
}
if (graph[node].low >= graph[node].time) {
Extract(graph, node, st, order);
}
}
vector<int> FindOrder(Graph& graph) {
vector<int> order;
order.reserve(graph.Size());
for (int i = 1; i <= graph.Size() / 2; i += 1) {
for (int sign = -1; sign <= 1; sign += 2) {
auto node = sign * i;
if (graph[node].time == -1) {
stack<int> st;
Dfs(graph, node, st, order);
}
}
}
reverse(order.begin(), order.end());
return order;
}
vector<bool> Solve(Graph& graph) {
unordered_map<int, bool> has_value;
for (const auto& node : FindOrder(graph)) {
if (graph[node].comp == graph[-node].comp) {
return vector<bool>{};
}
if (!has_value[node]) {
graph[node].value = false;
graph[-node].value = true;
has_value[node] = has_value[-node] = true;
}
}
vector<bool> res(graph.Size() / 2);
for (int i = 1; i <= graph.Size() / 2; i += 1) {
res[i - 1] = graph[i].value;
}
return res;
}
int main() {
ifstream fin("2sat.in");
ofstream fout("2sat.out");
int vars, conds;
fin >> vars >> conds;
Graph graph(vars);
for (int i = 0; i < conds; i += 1) {
int a, b;
fin >> a >> b;
graph.AddCond(a, b);
}
auto res = Solve(graph);
if (res.empty()) {
fout << "-1\n";
} else {
for (const auto& value : res) {
fout << (value ? 1 : 0) << " ";
}
fout << "\n";
}
return 0;
}