Pagini recente » Cod sursa (job #616648) | Cod sursa (job #2800675) | Cod sursa (job #2585399) | Cod sursa (job #934168) | Cod sursa (job #2848993)
#include <bits/stdc++.h>
using namespace std;
const int NMAX = (1e5 + 3);
int n, m;
vector<vector<int>>g(2 * NMAX + 1);
vector<vector<int>>gt(2 * NMAX + 1);
vector<int> value(NMAX + 1, -1);
vector<vector<int>>comps;
vector<int> contracted_node(2 * NMAX + 1);
vector<int> dg( 2 * NMAX + 1);
vector<int> used ( 2 * NMAX + 1);
vector<int> order;
int realIndex(int x, int n)
{
if ( x < 0 )
return -x + n;
return x;
}
void printValues(vector<vector<int>>&g)
{
int i;
cout << "Values: \n";
for (i = 1; i <= 2 * n; i++)
{
for (auto it : g[i])
cout << it << " ";
cout << "\n";
}
}
void computeRelation(int x, int y)
{
int real_x = realIndex(x, n);
int real_y = realIndex(y, n);
int real_non_x = realIndex(-x, n);
int real_non_y = realIndex(-y, n);
g[real_non_x].push_back(real_y);
gt[real_y].push_back(real_non_x);
g[real_non_y].push_back(real_x);
gt[real_x].push_back(real_non_y);
}
void dfs(int node)
{
used[node] = true;
for (int ngb: g[node])
{
if (!used[ngb])
dfs(ngb);
}
order.push_back(node);
}
void dfs_2(int node, vector<int>&act_comp)
{
used[node] = true;
act_comp.push_back(node);
for (auto ngb: gt[node])
{
if (!used[ngb])
dfs_2(ngb, act_comp);
}
}
void computeKosaraju()
{
for (int i = 1; i <= 2 * n; ++i)
if (!used[i])
dfs(i);
fill(used.begin(), used.end(), 0);
for (auto it = order.rbegin(); it != order.rend(); ++it)
if (!used[*it])
{
vector<int> act_comp;
dfs_2(*it, act_comp);
// merge nodes
for (auto it : act_comp)
contracted_node[it] = comps.size();
comps.push_back(act_comp);
}
}
bool checkIfPossible()
{
for (int i = 1; i <= n; i++)
{
int cnode_i = contracted_node[i];
int cnode_n = contracted_node[i + n];
if (contracted_node[i] == contracted_node[i + n])
return 0;
}
return 1;
}
void computeAssignment()
{
for (int node = 1; node <= 2 * n; node++)
{
for (auto ngb: g[node])
if (contracted_node[node] != contracted_node[ngb])
dg[contracted_node[ngb]]++;
}
queue<int>Q;
for (int i = 0; i < comps.size(); i++)
{
if (!dg[i])
Q.push(i);
}
while(!Q.empty())
{
int act = Q.front();
Q.pop();
for (auto node : comps[act])
{
int realVar = (node > n) ? node - n : node;
if (value[realVar] == -1)
value[realVar] = (node <= n) ? 0 : 1;
}
// decrease dg for adjacent components
for (auto node : comps[act])
{
for (auto ngb : g[node])
{
int cnode_node = contracted_node[node];
int cnode_ngb = contracted_node[ngb];
if (cnode_node != cnode_ngb)
{
dg[cnode_ngb]--;
if (!dg[cnode_ngb])
Q.push(cnode_ngb);
}
}
}
}
for (int i = 1; i <= n; ++i)
printf("%d ", value[i]);
}
int main()
{
freopen("2sat.in", "r", stdin);
freopen("2sat.out", "w", stdout);
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
computeRelation(x, y);
}
// printValues(g);
// printValues(gt);
computeKosaraju();
bool verdict = checkIfPossible();
if (!verdict)
{cout << -1; return 0;}
computeAssignment();
return 0;
}